Import opm-models

This commit is contained in:
Arne Morten Kvarving 2024-09-02 10:55:19 +02:00
commit bc46647aa5
368 changed files with 121393 additions and 0 deletions

View File

@ -0,0 +1,238 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Title: Ex2_Boundary.fig
%%Creator: fig2dev Version 3.2 Patchlevel 5
%%CreationDate: Fri Nov 14 16:44:03 2008
%%For: melanie@alvine (Melanie Darcis)
%%BoundingBox: 0 0 557 252
%Magnification: 1.0000
%%EndComments
/MyAppDict 100 dict dup begin def
/$F2psDict 200 dict def
$F2psDict begin
$F2psDict /mtrx matrix put
/col-1 {0 setgray} bind def
/col0 {0.000 0.000 0.000 srgb} bind def
/col1 {0.000 0.000 1.000 srgb} bind def
/col2 {0.000 1.000 0.000 srgb} bind def
/col3 {0.000 1.000 1.000 srgb} bind def
/col4 {1.000 0.000 0.000 srgb} bind def
/col5 {1.000 0.000 1.000 srgb} bind def
/col6 {1.000 1.000 0.000 srgb} bind def
/col7 {1.000 1.000 1.000 srgb} bind def
/col8 {0.000 0.000 0.560 srgb} bind def
/col9 {0.000 0.000 0.690 srgb} bind def
/col10 {0.000 0.000 0.820 srgb} bind def
/col11 {0.530 0.810 1.000 srgb} bind def
/col12 {0.000 0.560 0.000 srgb} bind def
/col13 {0.000 0.690 0.000 srgb} bind def
/col14 {0.000 0.820 0.000 srgb} bind def
/col15 {0.000 0.560 0.560 srgb} bind def
/col16 {0.000 0.690 0.690 srgb} bind def
/col17 {0.000 0.820 0.820 srgb} bind def
/col18 {0.560 0.000 0.000 srgb} bind def
/col19 {0.690 0.000 0.000 srgb} bind def
/col20 {0.820 0.000 0.000 srgb} bind def
/col21 {0.560 0.000 0.560 srgb} bind def
/col22 {0.690 0.000 0.690 srgb} bind def
/col23 {0.820 0.000 0.820 srgb} bind def
/col24 {0.500 0.190 0.000 srgb} bind def
/col25 {0.630 0.250 0.000 srgb} bind def
/col26 {0.750 0.380 0.000 srgb} bind def
/col27 {1.000 0.500 0.500 srgb} bind def
/col28 {1.000 0.630 0.630 srgb} bind def
/col29 {1.000 0.750 0.750 srgb} bind def
/col30 {1.000 0.880 0.880 srgb} bind def
/col31 {1.000 0.840 0.000 srgb} bind def
end
save
newpath 0 252 moveto 0 0 lineto 557 0 lineto 557 252 lineto closepath clip newpath
-72.8 457.3 translate
1 -1 scale
% left30
<<
/PatternType 1
/PaintType 2
/TilingType 2
/BBox [-2 -4 10 5]
/XStep 8
/YStep 4
/PaintProc
{
pop
newpath
.7 setlinewidth
-2 -1 moveto
12 6 rlineto
stroke
} bind
>>
matrix
makepattern
/P1 exch def
/cp {closepath} bind def
/ef {eofill} bind def
/gr {grestore} bind def
/gs {gsave} bind def
/sa {save} bind def
/rs {restore} bind def
/l {lineto} bind def
/m {moveto} bind def
/rm {rmoveto} bind def
/n {newpath} bind def
/s {stroke} bind def
/sh {show} bind def
/slc {setlinecap} bind def
/slj {setlinejoin} bind def
/slw {setlinewidth} bind def
/srgb {setrgbcolor} bind def
/rot {rotate} bind def
/sc {scale} bind def
/sd {setdash} bind def
/ff {findfont} bind def
/sf {setfont} bind def
/scf {scalefont} bind def
/sw {stringwidth} bind def
/tr {translate} bind def
/tnt {dup dup currentrgbcolor
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
bind def
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
4 -2 roll mul srgb} bind def
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
/$F2psEnd {$F2psEnteredState restore end} def
$F2psBegin
10 setmiterlimit
0 slj 0 slc
0.06299 0.06299 sc
%
% Fig objects follow
%
%
% here starts figure with depth 50
% Polyline
0 slj
0 slc
7.500 slw
n 3015 3870 m 8775 3870 l 8775 6615 l 3015 6615 l
cp gs col0 s gr
% Polyline
n 4095 4770 m 7650 4770 l 7650 5760 l 4095 5760 l
cp gs col31 1.00 shd ef gr gs col0 s gr
% Polyline
[15 45] 45 sd
n 3015 6615 m 8775 6615 l 8775 6795 l 3015 6795 l
cp
% Fill with pattern background color
gs /DeviceRGB setcolorspace 1.00 1.00 1.00 setcolor fill gr
% Fill with pattern pen color
gs /DeviceRGB setcolorspace 0.00 0.00 0.00 P1 setpattern fill gr
gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 3015 3690 m 8775 3690 l 8775 3870 l 3015 3870 l
cp
% Fill with pattern background color
gs /DeviceRGB setcolorspace 1.00 1.00 1.00 setcolor fill gr
% Fill with pattern pen color
gs /DeviceRGB setcolorspace 0.00 0.00 0.00 P1 setpattern fill gr
gs col0 s gr [] 0 sd
% Polyline
gs clippath
9320 4462 m 9465 4462 l 9465 4357 l 9320 4357 l 9320 4357 l 9440 4410 l 9320 4462 l cp
eoclip
n 9000 4410 m
9450 4410 l gs col0 s gr gr
% arrowhead
n 9320 4462 m 9440 4410 l 9320 4357 l col0 s
% Polyline
gs clippath
9320 4867 m 9465 4867 l 9465 4762 l 9320 4762 l 9320 4762 l 9440 4815 l 9320 4867 l cp
eoclip
n 9000 4815 m
9450 4815 l gs col0 s gr gr
% arrowhead
n 9320 4867 m 9440 4815 l 9320 4762 l col0 s
% Polyline
gs clippath
9320 5272 m 9465 5272 l 9465 5167 l 9320 5167 l 9320 5167 l 9440 5220 l 9320 5272 l cp
eoclip
n 9000 5220 m
9450 5220 l gs col0 s gr gr
% arrowhead
n 9320 5272 m 9440 5220 l 9320 5167 l col0 s
% Polyline
gs clippath
9320 5722 m 9465 5722 l 9465 5617 l 9320 5617 l 9320 5617 l 9440 5670 l 9320 5722 l cp
eoclip
n 9045 5670 m
9450 5670 l gs col0 s gr gr
% arrowhead
n 9320 5722 m 9440 5670 l 9320 5617 l col0 s
% Polyline
gs clippath
9320 6127 m 9465 6127 l 9465 6022 l 9320 6022 l 9320 6022 l 9440 6075 l 9320 6127 l cp
eoclip
n 9045 6075 m
9450 6075 l gs col0 s gr gr
% arrowhead
n 9320 6127 m 9440 6075 l 9320 6022 l col0 s
% Polyline
gs clippath
9320 6532 m 9465 6532 l 9465 6427 l 9320 6427 l 9320 6427 l 9440 6480 l 9320 6532 l cp
eoclip
n 9045 6480 m
9450 6480 l gs col0 s gr gr
% arrowhead
n 9320 6532 m 9440 6480 l 9320 6427 l col0 s
% Polyline
gs clippath
9320 4057 m 9465 4057 l 9465 3952 l 9320 3952 l 9320 3952 l 9440 4005 l 9320 4057 l cp
eoclip
n 9000 4005 m
9450 4005 l gs col0 s gr gr
% arrowhead
n 9320 4057 m 9440 4005 l 9320 3952 l col0 s
/Times-Roman ff 190.50 scf sf
5535 7245 m
gs 1 -1 sc (no flow) col0 sh gr
/Times-Roman ff 190.50 scf sf
5535 3420 m
gs 1 -1 sc (no flow) col0 sh gr
/Times-Roman ff 190.50 scf sf
9720 4995 m
gs 1 -1 sc (qw) col0 sh gr
/Times-Roman ff 190.50 scf sf
9765 5490 m
gs 1 -1 sc (qo) col0 sh gr
/Times-Roman ff 190.50 scf sf
1170 4815 m
gs 1 -1 sc (pw) col0 sh gr
/Times-Roman ff 190.50 scf sf
1170 5310 m
gs 1 -1 sc (S) col0 sh gr
% here ends figure;
$F2psEnd
rs
end
showpage
%%Trailer
%EOF

View File

@ -0,0 +1,245 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Title: Ex2_Domain.fig
%%Creator: fig2dev Version 3.2 Patchlevel 5
%%CreationDate: Wed Oct 6 11:40:41 2010
%%For: faigle@indo (Benjamin Faigle, Diplomarbeiter bei Jenny)
%%BoundingBox: 0 0 493 283
%Magnification: 1.0000
%%EndComments
%%BeginProlog
/$F2psDict 200 dict def
$F2psDict begin
$F2psDict /mtrx matrix put
/col-1 {0 setgray} bind def
/col0 {0.000 0.000 0.000 srgb} bind def
/col1 {0.000 0.000 1.000 srgb} bind def
/col2 {0.000 1.000 0.000 srgb} bind def
/col3 {0.000 1.000 1.000 srgb} bind def
/col4 {1.000 0.000 0.000 srgb} bind def
/col5 {1.000 0.000 1.000 srgb} bind def
/col6 {1.000 1.000 0.000 srgb} bind def
/col7 {1.000 1.000 1.000 srgb} bind def
/col8 {0.000 0.000 0.560 srgb} bind def
/col9 {0.000 0.000 0.690 srgb} bind def
/col10 {0.000 0.000 0.820 srgb} bind def
/col11 {0.530 0.810 1.000 srgb} bind def
/col12 {0.000 0.560 0.000 srgb} bind def
/col13 {0.000 0.690 0.000 srgb} bind def
/col14 {0.000 0.820 0.000 srgb} bind def
/col15 {0.000 0.560 0.560 srgb} bind def
/col16 {0.000 0.690 0.690 srgb} bind def
/col17 {0.000 0.820 0.820 srgb} bind def
/col18 {0.560 0.000 0.000 srgb} bind def
/col19 {0.690 0.000 0.000 srgb} bind def
/col20 {0.820 0.000 0.000 srgb} bind def
/col21 {0.560 0.000 0.560 srgb} bind def
/col22 {0.690 0.000 0.690 srgb} bind def
/col23 {0.820 0.000 0.820 srgb} bind def
/col24 {0.500 0.190 0.000 srgb} bind def
/col25 {0.630 0.250 0.000 srgb} bind def
/col26 {0.750 0.380 0.000 srgb} bind def
/col27 {1.000 0.500 0.500 srgb} bind def
/col28 {1.000 0.630 0.630 srgb} bind def
/col29 {1.000 0.750 0.750 srgb} bind def
/col30 {1.000 0.880 0.880 srgb} bind def
/col31 {1.000 0.840 0.000 srgb} bind def
end
save
newpath 0 283 moveto 0 0 lineto 493 0 lineto 493 283 lineto closepath clip newpath
-132.3 508.2 translate
1 -1 scale
/cp {closepath} bind def
/ef {eofill} bind def
/gr {grestore} bind def
/gs {gsave} bind def
/sa {save} bind def
/rs {restore} bind def
/l {lineto} bind def
/m {moveto} bind def
/rm {rmoveto} bind def
/n {newpath} bind def
/s {stroke} bind def
/sh {show} bind def
/slc {setlinecap} bind def
/slj {setlinejoin} bind def
/slw {setlinewidth} bind def
/srgb {setrgbcolor} bind def
/rot {rotate} bind def
/sc {scale} bind def
/sd {setdash} bind def
/ff {findfont} bind def
/sf {setfont} bind def
/scf {scalefont} bind def
/sw {stringwidth} bind def
/tr {translate} bind def
/tnt {dup dup currentrgbcolor
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
bind def
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
4 -2 roll mul srgb} bind def
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
/$F2psEnd {$F2psEnteredState restore end} def
$F2psBegin
10 setmiterlimit
0 slj 0 slc
0.06299 0.06299 sc
%%EndProlog
%
% Fig objects follow
%
%
% here starts figure with depth 50
% Polyline
0 slj
0 slc
7.500 slw
n 3015 3870 m 8775 3870 l 8775 6615 l 3015 6615 l
cp gs col0 s gr
% Polyline
n 2610 3870 m
2610 4950 l gs col0 s gr
% Polyline
n 2610 5535 m
2610 6615 l gs col0 s gr
% Polyline
n 6435 3690 m
8775 3690 l gs col0 s gr
% Polyline
n 4860 5805 m
4860 6075 l gs col0 s gr
% Polyline
n 4860 6390 m
4860 6615 l gs col0 s gr
% Polyline
n 3870 4770 m
3870 5085 l gs col0 s gr
% Polyline
n 3870 5445 m
3870 5760 l gs col0 s gr
% Polyline
n 3915 4770 m
3780 4770 l gs col0 s gr
% Polyline
n 3915 5760 m
3780 5760 l gs col0 s gr
% Polyline
n 3015 3690 m
5355 3690 l gs col0 s gr
% Polyline
n 4140 4590 m
5580 4590 l gs col0 s gr
% Polyline
n 6390 4590 m
7650 4590 l gs col0 s gr
% Polyline
n 8550 5220 m
8775 5220 l gs col0 s gr
% Polyline
n 7695 5220 m
7920 5220 l gs col0 s gr
% Polyline
n 4095 4770 m 7650 4770 l 7650 5760 l 4095 5760 l
cp gs col31 1.00 shd ef gr gs col0 s gr
% Polyline
gs clippath
6113 5413 m 5991 5322 l 5955 5370 l 6077 5461 l 6077 5461 l 6023 5383 l 6113 5413 l cp
eoclip
n 7965 6840 m
5985 5355 l gs col0 s gr gr
% arrowhead
30.000 slw
n 6113 5413 m 6023 5383 l 6077 5461 l 6119 5455 l 6113 5413 l
cp gs 0.00 setgray ef gr col0 s
% Polyline
7.500 slw
gs clippath
6073 6363 m 6196 6273 l 6161 6224 l 6038 6314 l 6038 6314 l 6129 6286 l 6073 6363 l cp
eoclip
n 5380 6827 m
6167 6258 l gs col0 s gr gr
% arrowhead
30.000 slw
n 6073 6363 m 6129 6286 l 6038 6314 l 6031 6356 l 6073 6363 l
cp gs 0.00 setgray ef gr col0 s
% Polyline
7.500 slw
n 2700 3870 m
2565 3870 l gs col0 s gr
% Polyline
n 2700 6615 m
2565 6615 l gs col0 s gr
% Polyline
n 3015 3780 m
3015 3600 l gs col0 s gr
% Polyline
n 8775 3780 m
8775 3600 l gs col0 s gr
% Polyline
n 7650 4680 m
7650 4500 l gs col0 s gr
% Polyline
n 4095 4680 m
4095 4500 l gs col0 s gr
% Polyline
[15 45] 45 sd
n 6615 6840 m 9900 6840 l 9900 8055 l 6615 8055 l
cp gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 2835 6840 m 6075 6840 l 6075 8055 l 2835 8055 l
cp gs col0 s gr [] 0 sd
/Times-Roman ff 190.50 scf sf
7965 5265 m
gs 1 -1 sc (L3x) col0 sh gr
/Times-Roman ff 190.50 scf sf
5670 4635 m
gs 1 -1 sc (L2x) col0 sh gr
/Times-Roman ff 190.50 scf sf
5445 3780 m
gs 1 -1 sc (L1x) col0 sh gr
/Times-Roman ff 190.50 scf sf
4455 6300 m
gs 1 -1 sc (H2y) col0 sh gr
/Times-Roman ff 190.50 scf sf
3330 5310 m
gs 1 -1 sc (H3y) col0 sh gr
/Times-Roman ff 190.50 scf sf
2115 5310 m
gs 1 -1 sc (H1y) col0 sh gr
/Times-Roman ff 190.50 scf sf
2970 7695 m
gs 1 -1 sc (Lin) col0 sh gr
/Times-Roman ff 190.50 scf sf
2970 7425 m
gs 1 -1 sc (phi1) col0 sh gr
/Times-Roman ff 190.50 scf sf
2970 7155 m
gs 1 -1 sc (K1) col0 sh gr
/Times-Roman ff 190.50 scf sf
6750 7155 m
gs 1 -1 sc (K2) col0 sh gr
/Times-Roman ff 190.50 scf sf
6750 7380 m
gs 1 -1 sc (phi2) col0 sh gr
/Times-Roman ff 190.50 scf sf
6750 7650 m
gs 1 -1 sc (BC1) col0 sh gr
/Times-Roman ff 190.50 scf sf
6750 7920 m
gs 1 -1 sc (BC2) col0 sh gr
/Times-Roman ff 190.50 scf sf
2970 7920 m
gs 1 -1 sc (Lin2) col0 sh gr
% here ends figure;
$F2psEnd
rs
showpage
%%Trailer
%EOF

759
doc/handbook/EPS/box_disc.eps Executable file
View File

@ -0,0 +1,759 @@
%!PS-Adobe-3.0 EPSF-3.0
%%Creator: cairo 1.8.10 (http://cairographics.org)
%%CreationDate: Tue Jan 4 12:08:49 2011
%%Pages: 1
%%BoundingBox: 0 0 729 467
%%DocumentData: Clean7Bit
%%LanguageLevel: 2
%%EndComments
%%BeginProlog
/cairo_eps_state save def
/dict_count countdictstack def
/op_count count 1 sub def
userdict begin
/q { gsave } bind def
/Q { grestore } bind def
/cm { 6 array astore concat } bind def
/w { setlinewidth } bind def
/J { setlinecap } bind def
/j { setlinejoin } bind def
/M { setmiterlimit } bind def
/d { setdash } bind def
/m { moveto } bind def
/l { lineto } bind def
/c { curveto } bind def
/h { closepath } bind def
/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto
0 exch rlineto 0 rlineto closepath } bind def
/S { stroke } bind def
/f { fill } bind def
/f* { eofill } bind def
/B { fill stroke } bind def
/B* { eofill stroke } bind def
/n { newpath } bind def
/W { clip } bind def
/W* { eoclip } bind def
/BT { } bind def
/ET { } bind def
/pdfmark where { pop globaldict /?pdfmark /exec load put }
{ globaldict begin /?pdfmark /pop load def /pdfmark
/cleartomark load def end } ifelse
/BDC { mark 3 1 roll /BDC pdfmark } bind def
/EMC { mark /EMC pdfmark } bind def
/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def
/Tj { show currentpoint cairo_store_point } bind def
/TJ {
{
dup
type /stringtype eq
{ show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse
} forall
currentpoint cairo_store_point
} bind def
/cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore
cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def
/Tf { pop /cairo_font exch def /cairo_font_matrix where
{ pop cairo_selectfont } if } bind def
/Td { matrix translate cairo_font_matrix matrix concatmatrix dup
/cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point
/cairo_font where { pop cairo_selectfont } if } bind def
/Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def
cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def
/g { setgray } bind def
/rg { setrgbcolor } bind def
/d1 { setcachedevice } bind def
%%EndProlog
11 dict begin
/FontType 42 def
/FontName /f-0-0 def
/PaintType 0 def
/FontMatrix [ 1 0 0 1 0 0 ] def
/FontBBox [ 0 0 0 0 ] def
/Encoding 256 array def
0 1 255 { Encoding exch /.notdef put } for
Encoding 1 /uni0073 put
Encoding 2 /uni0063 put
Encoding 3 /uni0076 put
Encoding 4 /uni0069 put
Encoding 5 /uni006B put
Encoding 6 /uni0046 put
Encoding 7 /uni0045 put
Encoding 8 /uni0020 put
Encoding 9 /uni006D put
Encoding 10 /uni0065 put
Encoding 11 /uni0068 put
Encoding 12 /uni006F put
Encoding 13 /uni006E put
Encoding 14 /uni0064 put
Encoding 15 /uni0061 put
Encoding 16 /uni0072 put
Encoding 17 /uni0079 put
Encoding 18 /uni0056 put
Encoding 19 /uni0042 put
Encoding 20 /uni006A put
Encoding 21 /uni0078 put
Encoding 22 /uni0029 put
Encoding 23 /uni0062 put
/CharStrings 24 dict dup begin
/.notdef 0 def
/uni0073 1 def
/uni0063 2 def
/uni0076 3 def
/uni0069 4 def
/uni006B 5 def
/uni0046 6 def
/uni0045 7 def
/uni0020 8 def
/uni006D 9 def
/uni0065 10 def
/uni0068 11 def
/uni006F 12 def
/uni006E 13 def
/uni0064 14 def
/uni0061 15 def
/uni0072 16 def
/uni0079 17 def
/uni0056 18 def
/uni0042 19 def
/uni006A 20 def
/uni0078 21 def
/uni0029 22 def
/uni0062 23 def
end readonly def
/sfnts [
<00010000000a008000030020636d617000baf144000011f00000006e63767420ffd31d390000
1260000001fc6670676de7b4f1c40000145c0000008b676c7966e58152c0000000ac00001144
68656164dd84a2d0000014e800000036686865611045077b0000152000000024686d74786d08
0bd000001544000000606c6f636136303068000015a4000000326d6178700453063a000015d8
00000020707265703b07f100000015f80000056800020066fe96046605a400030007001a400c
04fb0006fb0108057f0204002fc4d4ec310010d4ecd4ec301311211125211121660400fc7303
1bfce5fe96070ef8f27206290001006fffe303c7047b002700e7403c0d0c020e0b531f1e0809
02070a531e1f1e420a0b1e1f041500860189041486158918b91104b925b8118c281e0a0b1f1b
0700521b080e07081422452810fcc4ecd4ece4111239393939310010e4f4ec10fef5ee10f5ee
121739304b535807100eed111739070eed1117395922b2002701015d406d1c0a1c0b1c0c2e09
2c0a2c0b2c0c3b093b0a3b0b3b0c0b200020012402280a280b2a132f142f152a16281e281f29
2029212427860a860b860c860d12000000010202060a060b030c030d030e030f03100319031a
031b031c041d09272f293f295f297f2980299029a029f029185d005d7101152e012322061514
161f011e0115140623222627351e013332363534262f012e01353436333216038b4ea85a8989
62943fc4a5f7d85ac36c66c661828c65ab40ab98e0ce66b4043fae282854544049210e2a9989
9cb62323be353559514b50250f2495829eac1e00000000010071ffe303e7047b0019003f401b
00860188040e860d880ab91104b917b8118c1a07120d004814451a10fce432ec310010e4f4ec
10fef4ee10f5ee30400b0f1b101b801b901ba01b05015d01152e012322061514163332363715
0e0123220011100021321603e74e9d50b3c6c6b3509d4e4da55dfdfed6012d010655a20435ac
2b2be3cdcde32b2baa2424013e010e0112013a2300000001003d0000047f0460000601124027
03110405040211010205050402110302060006011100000642020300bf050605030201050400
0710d4c4173931002fec3239304b5358071005ed071008ed071008ed071005ed5922014bb00a
5458bd0007ffc000010007000700403811373859014bb014544bb015545b58bd000700400001
00070007ffc03811373859408e48026a027b027f02860280029102a402080600060109030904
150015011a031a0426002601290329042008350035013a033a04300846004601490349044605
48064008560056015903590450086600660169036904670568066008750074017b037b047505
7a068500850189038904890586069600960197029a03980498059706a805a706b008c008df08
ff083e5d005d133309013301233dc3015e015ec3fe5cfa0460fc5403acfba0000000000200c1
00000179061400030007002b400e06be04b100bc020501080400460810fc3cec3231002fe4fc
ec30400b1009400950096009700905015d1333112311331523c1b8b8b8b80460fba00614e900
000100ba0000049c0614000a00bc402908110506050711060605031104050402110505044208
05020303bc009709060501040608010800460b10fcec32d4c4113931002f3cece41739304b53
58071004ed071005ed071005ed071004ed5922b2100c01015d405f04020a081602270229052b
0856026602670873027705820289058e08930296059708a3021209050906020b030a07280327
0428052b062b07400c6803600c8903850489058d068f079a039707aa03a705b607c507d607f7
03f003f704f0041a5d71005d1333110133090123011123bab90225ebfdae026bf0fdc7b90614
fc6901e3fdf4fdac0223fddd000100c90000042305d50009002940120695040295008104ad08
050107031c00040a10fcec32d4c431002fecf4ec10ee30b20f0b01015d132115211121152111
23c9035afd700250fdb0ca05d5aafe48aafd3700000100c90000048b05d5000b002e40150695
0402950081089504ad0a05010907031c00040c10fcec32d4c4c431002fececf4ec10ee30b21f
0d01015d132115211121152111211521c903b0fd1a02c7fd3902f8fc3e05d5aafe46aafde3aa
0000000100ba0000071d047b0022005a4026061209180f00061d07150c871d2003b81bbc1910
0700110f0808065011080f501c18081a462310fcec32fcfcfcec11123931002f3c3ce4f43cc4
ec32111217393040133024502470249024a024a024bf24df24ff2409015d013e013332161511
231134262322061511231134262322061511231133153e01333216042945c082afbeb972758f
a6b972778da6b9b93fb0797aab03897c76f5e2fd5c029ea19cbea4fd87029ea29bbfa3fd8704
60ae67627c00000000020071ffe3047f047b0014001b00704024001501098608880515a90105
b90c01bb18b912b80c8c1c1b1502081508004b02120f451c10fcecf4ecc4111239310010e4f4
ece410ee10ee10f4ee1112393040293f1d701da01dd01df01d053f003f013f023f153f1b052c
072f082f092c0a6f006f016f026f156f1b095d71015d0115211e0133323637150e0123200011
1000333200072e0123220607047ffcb20ccdb76ac76263d06bfef4fec70129fce20107b802a5
889ab90e025e5abec73434ae2a2c0138010a01130143feddc497b4ae9e00000100ba00000464
0614001300344019030900030e0106870e11b80c970a010208004e0d09080b461410fcec32f4
ec31002f3cecf4c4ec1112173930b2601501015d0111231134262322061511231133113e0133
32160464b87c7c95acb9b942b375c1c602a4fd5c029e9f9ebea4fd870614fd9e6564ef000002
0071ffe30475047b000b0017004a401306b91200b90cb8128c1809120f51031215451810fcec
f4ec310010e4f4ec10ee3040233f197b007b067f077f087f097f0a7f0b7b0c7f0d7f0e7f0f7f
107f117b12a019f01911015d0122061514163332363534262732001110002322001110000273
94acab9593acac93f00112feeef0f1feef011103dfe7c9c9e7e8c8c7e99cfec8feecfeedfec7
01390113011401380000000100ba00000464047b001300364019030900030e0106870e11b80c
bc0a010208004e0d09080b461410fcec32f4ec31002f3ce4f4c4ec1112173930b46015cf1502
015d0111231134262322061511231133153e013332160464b87c7c95acb9b942b375c1c602a4
fd5c029e9f9ebea4fd870460ae6564ef00020071ffe3045a06140010001c003840191ab9000e
14b905088c0eb801970317040008024711120b451d10fcecf4ec323231002fece4f4c4ec10c4
ee30b6601e801ea01e03015d0111331123350e01232202111012333216011416333236353426
23220603a2b8b83ab17ccbffffcb7cb1fdc7a79292a8a89292a703b6025ef9eca86461014401
080108014461fe15cbe7e7cbcbe7e7000002007bffe3042d047b000a002500bc4027191f0b17
090e00a91706b90e1120861fba1cb923b8118c170c001703180d09080b1f030814452610fcec
ccd4ec323211393931002fc4e4f4fcf4ec10c6ee10ee11391139123930406e301d301e301f30
20302130223f27401d401e401f402040214022501d501e501f50205021502250277027851d87
1e871f8720872185229027a027f0271e301e301f30203021401e401f40204021501e501f5020
5021601e601f60206021701e701f70207021801e801f80208021185d015d0122061514163332
363d01371123350e01232226353436332135342623220607353e0133321602bedfac816f99b9
b8b83fbc88accbfdfb0102a79760b65465be5af3f00233667b6273d9b4294cfd81aa6661c1a2
bdc0127f8b2e2eaa2727fc00000100ba0000034a047b001100304014060b0700110b03870eb8
09bc070a06080008461210fcc4ec3231002fe4f4ecc4d4cc11123930b450139f1302015d012e
012322061511231133153e0133321617034a1f492c9ca7b9b93aba85132e1c03b41211cbbefd
b20460ae6663050500000001003dfe56047f0460000f01a240430708020911000f0a110b0a00
000f0e110f000f0d110c0d00000f0d110e0d0a0b0a0c110b0b0a420d0b0910000b058703bd0e
0bbc100e0d0c0a09060300080f040f0b1010d4c4c4111739310010e432f4ec11391139123930
4b5358071005ed071008ed071008ed071005ed071008ed0705ed17325922014bb00a544bb008
545b58bd0010ffc000010010001000403811373859014bb0145458bd00100040000100100010
ffc0381137385940f0060005080609030d160a170d100d230d350d490a4f0a4e0d5a095a0a6a
0a870d800d930d120a000a09060b050c0b0e0b0f1701150210041005170a140b140c1a0e1a0f
2700240124022004200529082809250a240b240c270d2a0e2a0f201137003501350230043005
380a360b360c380d390e390f30114100400140024003400440054006400740084209450a470d
490e490f40115400510151025503500450055606550756085709570a550b550c590e590f5011
66016602680a690e690f60117b08780e780f89008a09850b850c890d890e890f9909950b950c
9a0e9a0fa40ba40cab0eab0fb011cf11df11ff11655d005d050e012b01353332363f01013309
013302934e947c936c4c543321fe3bc3015e015ec368c87a9a488654044efc94036c00010010
0000056805d5000600b740270411050605031102030606050311040300010002110101004203
0401af0006040302000505010710d4c4173931002fec3239304b5358071005ed071008ed0710
08ed071005ed5922b2500801015d406200032a03470447055a037d0383030706000702080409
06150114021a041a052a002601260229042905250620083800330133023c043c053706480045
014502490449054706590056066602690469057a007601760279047905750680089800970629
5d005d21013309013301024afdc6d301d901dad2fdc705d5fb1704e9fa2b000300c9000004ec
05d5000800110020004340231900950a0995128101950aad1f110b080213191f05000e1c1605
191c2e09001c12042110fcec32fcecd4ec111739393931002fececf4ec10ee3930b20f220101
5d01112132363534262301112132363534262325213216151406071e01151404232101930144
a39d9da3febc012b94919194fe0b0204e7fa807c95a5fef0fbfde802c9fddd878b8c850266fe
3e6f727170a6c0b189a21420cb98c8da0002ffdbfe5601790614000b000f0044401c0b020700
0ebe0c078705bd00bc0cb110081005064f0d01080c00461010fc3cec32e4391239310010ece4
f4ec10ee1112393930400b1011401150116011701105015d13331114062b0135333236351133
1523c1b8a3b54631694cb8b80460fb8cd6c09c61990628e900000001003b000004790460000b
015a40460511060706041103040707060411050401020103110202010b110001000a11090a01
01000a110b0a0708070911080807420a070401040800bf05020a0704010408000208060c10d4
c4d4c411173931002f3cec321739304b5358071005ed071008ed071008ed071005ed071005ed
071008ed071008ed071005ed5922014bb00a544bb00f545b4bb010545b4bb011545b58bd000c
ffc00001000c000c00403811373859014bb0145458bd000c00400001000c000cffc038113738
5940980a04040a1a04150a260a3d04310a55045707580a660a76017a047607740a8d04820a99
049f049707920a900aa601a904af04a507a30aa00a1c0a03040505090a0b1a03150515091a0b
2903260525092a0b200d3a013903370534073609390b300d4903460545094a0b400d59005601
5902590357055606590756085609590b500d6f0d78017f0d9b019407ab01a407b00dcf0ddf0d
ff0d2f5d005d09022309012309013309010464fe6b01aad9febafebad901b3fe72d901290129
0460fddffdc101b8fe48024a0216fe71018f0000000100a4fef2026f0612000d001f400f0798
00970e0701000b12041308000e10dc3cf4ec113939310010fcec301333161215140207233612
353402a4a096959596a08583830612ecfe3cdfe0fe3aebe501c5e7e701c20000000200baffe3
04a40614000b001c0038401903b90c0f09b918158c0fb81b971900121247180c06081a461d10
fcec3232f4ec31002fece4f4c4ec10c6ee30b6601e801ea01e03015d01342623220615141633
3236013e01333212111002232226271523113303e5a79292a7a79292a7fd8e3ab17bccffffcc
7bb13ab9b9022fcbe7e7cbcbe7e702526461febcfef8fef8febc6164a8061400000000020003
00000000001400010000000000340004002000000004000400010000f017ffff0000f000ffff
10000001000000000006003a0000000000180000000100020003000400050006000700080009
000a000b000c000d000e000f001000110012001300140015001600170000013500b800cb00cb
00c100aa009c01a600b800660000007100cb00a002b20085007500b800c301cb0189022d00cb
00a600f000d300aa008700cb03aa0400014a003300cb000000d9050200f4015400b4009c0139
0114013907060400044e04b4045204b804e704cd0037047304cd04600473013303a2055605a6
0556053903c5021200c9001f00b801df007300ba03e9033303bc0444040e00df03cd03aa00e5
03aa0404000000cb008f00a4007b00b80014016f007f027b0252008f00c705cd009a009a006f
00cb00cd019e01d300f000ba018300d5009803040248009e01d500c100cb00f600830354027f
00000333026600d300c700a400cd008f009a0073040005d5010a00fe022b00a400b4009c0000
0062009c0000001d032d05d505d505d505f0007f007b005400a406b80614072301d300b800cb
00a601c301ec069300a000d3035c037103db0185042304a80448008f0139011401390360008f
05d5019a0614072306660179046004600460047b009c00000277046001aa00e904600762007b
00c5007f027b000000b4025205cd006600bc00660077061000cd013b01850389008f007b0000
001d00cd074a042f009c009c0000077d006f0000006f0335006a006f007b00ae00b2002d0396
008f027b00f600830354063705f6008f009c04e10266008f018d02f600cd03440029006604ee
007300001400b6060504030201002c2010b002254964b040515820c859212d2cb002254964b0
40515820c859212d2c20100720b00050b00d7920b8ffff5058041b0559b0051cb0032508b004
2523e120b00050b00d7920b8ffff5058041b0559b0051cb0032508e12d2c4b505820b0fd4544
59212d2cb002254560442d2c4b5358b00225b0022545445921212d2c45442d00000100000002
00005d2045f85f0f3cf5001f080000000000bab9f0b800000000bac26791fe89fe1d0a4c076d
00000008000100000000000000010000076dfe1d00000abcfe89fe890a4c0001000000000000
0000000000000000001804cd0066042b006f0466007104bc003d023900c104a200ba049a00c9
050e00c9028b000007cb00ba04ec0071051200ba04e50071051200ba0514007104e7007b034a
00ba04bc003d05790010057d00c90239ffdb04bc003b031f00a4051400ba0000002200d2011e
01bc01e4025c028602b602b60318038203be0410044c0498052e0566065606c6071e075c082a
085608a20000000100000018004d000700420004000200100040000700000415056800030001
b8028040fffbfe03fa1403f92503f83203f79603f60e03f5fe03f4fe03f32503f20e03f19603
f02503ef8a4105effe03ee9603ed9603ecfa03ebfa03eafe03e93a03e84203e7fe03e63203e5
e45305e59603e48a4105e45303e3e22f05e3fa03e22f03e1fe03e0fe03df3203de1403dd9603
dcfe03db1203da7d03d9bb03d8fe03d68a4105d67d03d5d44705d57d03d44703d3d21b05d3fe
03d21b03d1fe03d0fe03cffe03cefe03cd9603cccb1e05ccfe03cb1e03ca3203c9fe03c68511
05c61c03c51603c4fe03c3fe03c2fe03c1fe03c0fe03bffe03befe03bdfe03bcfe03bbfe03ba
1103b9862505b9fe03b8b7bb05b8fe03b7b65d05b7bb03b78004b6b52505b65d40ff03b64004
b52503b4fe03b39603b2fe03b1fe03b0fe03affe03ae6403ad0e03acab2505ac6403abaa1205
ab2503aa1203a98a4105a9fa03a8fe03a7fe03a6fe03a51203a4fe03a3a20e05a33203a20e03
a16403a08a4105a096039ffe039e9d0c059efe039d0c039c9b19059c64039b9a10059b19039a
1003990a0398fe0397960d0597fe03960d03958a410595960394930e05942803930e0392fa03
9190bb0591fe03908f5d0590bb039080048f8e25058f5d038f40048e25038dfe038c8b2e058c
fe038b2e038a8625058a410389880b05891403880b0387862505876403868511058625038511
0384fe038382110583fe0382110381fe0380fe037ffe0340ff7e7d7d057efe037d7d037c6403
7b5415057b25037afe0379fe03780e03770c03760a0375fe0374fa0373fa0372fa0371fa0370
fe036ffe036efe036c21036bfe036a1142056a530369fe03687d036711420566fe0365fe0364
fe0363fe0362fe03613a0360fa035e0c035dfe035bfe035afe0359580a0559fa03580a035716
190557320356fe035554150555420354150353011005531803521403514a130551fe03500b03
4ffe034e4d10054efe034d10034cfe034b4a13054bfe034a4910054a1303491d0d0549100348
0d0347fe0346960345960344fe0343022d0543fa0342bb03414b0340fe033ffe033e3d12053e
14033d3c0f053d12033c3b0d053c40ff0f033b0d033afe0339fe033837140538fa0337361005
37140336350b05361003350b03341e03330d0332310b0532fe03310b03302f0b05300d032f0b
032e2d09052e10032d09032c32032b2a25052b64032a2912052a250329120328272505284103
27250326250b05260f03250b0324fe0323fe03220f03210110052112032064031ffa031e1d0d
051e64031d0d031c1142051cfe031bfa031a42031911420519fe031864031716190517fe0316
01100516190315fe0314fe0313fe031211420512fe0311022d05114203107d030f64030efe03
0d0c16050dfe030c0110050c16030bfe030a100309fe0308022d0508fe030714030664030401
100504fe03401503022d0503fe0302011005022d0301100300fe0301b80164858d012b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b002b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b1d00>
] def
FontName currentdict end definefont pop
11 dict begin
/FontType 42 def
/FontName /f-1-0 def
/PaintType 0 def
/FontMatrix [ 1 0 0 1 0 0 ] def
/FontBBox [ 0 0 0 0 ] def
/Encoding 256 array def
0 1 255 { Encoding exch /.notdef put } for
Encoding 1 /uni006E put
/CharStrings 2 dict dup begin
/.notdef 0 def
/uni006E 1 def
end readonly def
/sfnts [
<00010000000a008000030020636d61700015f07e0000018000000042637674203eb92de20000
01c4000002526670676dc6703916000004180000008c676c796648f0b128000000ac000000d4
68656164de68ad49000004a40000003668686561112e080d000004dc00000024686d74780a7f
011200000500000000086c6f6361006a002600000508000000066d6178700614087d00000510
00000020707265707c61a2e700000530000007a700020066fe96046605a400030007001fbc00
040126000000060126b6010805890204002fc4d4ec310010d4ecd4ec30131121112521112166
0400fc73031bfce5fe96070ef8f2720629000000000100ac00000512047b0017003540180d04
00010adb12d015ca10b30e01020d0047110d0d0f101810fcec32f4ec31002f3ce4f4e4ec1139
393930b46019801902015d01112135113426272e012322061511211121153e013332160512fe
980d1015482e7080fe9a016651b66ec2c902aafd566f019b916e1a2327ad99fdd90460a4625d
ee00000000000002000300000000001400010000000000340004002000000004000400010000
f001ffff0000f000ffff10000001000000000006000e00000000000200000001000001660133
016600bc00e90000013d00a200fa031f00020002006601660002000200ac015400ec00bc0062
01660181048501540166016d04a400020166007f04cd000000020133006200710000002504a4
01bc00ba00e500660181018d0548055a0166016d000000000002000200f605c301f005390239
0058046d043d04b2048104b2016601750466048100b00466043902d1049c047b04cf047b0058
01330166014c0166014c000200ac009a014a0123009a029a01440119014402cd00c100000166
013f019a013b05cb05cb00d500d5015000ac00ac0077020a01c701f2012f015801b2012300f6
00f6011f012f0135023501ee01e70133009800d10358050a009a008f0112009800bc00cd00e5
00e500f2007304000166008f05d5022b05d500c300e100d700e50000006a01020000001d032d
05d505d505f000a8006a00ec00e1010205d506140721046602f800ec018302a602f801230102
01020112011f031f005e03cd046004c7048900ec01bc00ba01020333031f03420333035c0112
011f05d5019a009a00e106660179046004600460047b000000ec02c302b802cd00be00dd00d5
0000006a025c027b029a00dd01ae01ba01120000008501ae04600762041b009a069a045800ee
009a029a00d102cd019a015005cb05cb008b008b063100f6040600f0034c016004a800c10000
002505c101000121074a06120096014a078300a800000337007b0014000000c9010005c105c1
05c105c101000108061d00960427039e00ec0102027d0133009800d10358017900cd02390362
009c009c009c009301b8009300b80073000014000000b6060504030201002c2010b002254964
b040515820c859212d2cb002254964b040515820c859212d2c20100720b00050b00d7920b8ff
ff5058041b0559b0051cb0032508b0042523e120b00050b00d7920b8ffff5058041b0559b005
1cb0032508e12d2c4b505820b80128454459212d2cb002254560442d2c4b5358b00225b00225
45445921212d2c45442d0001000000020000031875265f0f3cf5001f080000000000bab9cc10
00000000babc96b2fe68fe1d0b56076d00010008000100000000000000010000076dfe1d0000
0b85fe68fe680b5600010000000000000000000000000000000204cd006605b200ac00000026
006a0000000100000002004e0007004500040002001000400007000005ed07a7000200014184
0280012600fe000301250011000301240121003a0005012400fa000301230016000301220121
003a0005012200fe00030121003a0003012000fa0003011f00bb0003011e00640003011d00fe
0003011c00190003011b001e0003011a00fe0003011900fe0003011800fe0003011700fe0003
011600fe000301150114000e0005011500fe00030114000e0003011300fe0003011200fe0003
010f010e007d0005010f00fe0003010e007d0003010d010c008c0005010d00fe0003010d00c0
0004010c010b00590005010c008c0003010c00800004010b010a00260005010b00590003010b
00400004010a00260003010900fe0003010800fe00030107000c00030107008000040106b297
2e054113010600fa0003010500fa0003010400fe0003010300190003010200fa0003010100fa
0003010040ff7d03ff3e03fefe03fcfb2c05fcfe03fb2c03fafe03f9f84705f97d03f84703f7
fa03f6fe03f5fe03f4fe03f3bb03f2fe03f1fe03f0fe03ef1e03eefe03edec0a05edfe03ec0a
03ec4004ebea0a05eb3203ea0a03e9fa03e8911605e8fe03e7fa03e6fa03e5911605e5fe03e4
fe03e3fe03e2fe03e1fe03e0fe03dffe03defa03dddc1805dd6403dc1803dba01e05db6403da
d92505dafa03d92503d8d12505d8fa03d7d61405d71603d6d51005d61403d51003d4d30b05d4
2003d30b03d2d12505d2fa03d1911605d12503d0940c05d02303cfce1405cf2603cecd1205ce
1403cd1203cc911605cc1d03cb1403cac9bb05cafe03c9c85d05c9bb03c98004c840ffc72505
c85d03c84004c72503c6fe03c56403c4901005c4fe03c31c03c2fe03c1fe03c0bf3a05c0fa03
bfad1b05bf3a03bebd1a05be3203bdbc1105bd1a03bcbb0f05bc1103bbba0c05bb0f03ba0c03
b9911605b9fe03b8fe03b71503b61203b5fe03b4fe03b3fe03b21703b11903b01603afad1b05
affa03aead1b05aefa03ad911605ad1b03ac911605ac7d03abfe03aa2603a9fe03a8fe03a7fe
03a6fe03a50a03a4fe03a3a20e05a3fe03a20e03a24004a1a01e05a1fa03a0911605a01e039f
9116059ffa039e940c059e1c039dfe039c9bbb059cfe039b9a5d059bbb039b80049a8f25059a
5d039a400499fe0398972e0598fe03972e0396911605961e40ff0395940c05952003940c0393
911605934b039291160592fe03919010059116039010038f25038efe038dfe038cfe038bfe03
8afe0389fe038887250588fe0387250386fe0385fe0384320383960382fe0381fe038019037f
0a037efe037dfe037cfe037bfa037afa0379fe037776a60577fe0376a60375741b0575fa0374
1b0373fa03727d0371fe03706f2c056f2c036efa036dfa036cfa036bfe036afe0369fe036863
0c0568320367fe0366320365640a0565fe03640a0364400463620a05630c03620a0361601505
619603600111056015035f0a035efe035dfe035c0111055cfe035b5a1b055bfe035a0111055a
1b0359fe0358fa0357fe035601110540ff56fe0355fe03541e035314035251190552fa035101
1105511903504f190550fa034f4e11054f19034e11034d1e034c4b14054c15034b4a11054b14
034a490e054a1103490e0348fa034746140547150346140345fa0344430e05440f03430e0342
41250542fa0341011105412503403f0f0540fe033f3e0e053f0f033e0e033d3c0d053d16033c
0d033b64033afe0339140338fe0337130336351a0536250335341405351a0335c004340a0d05
34140334800433320c05331403334004320c033130a60531fe033001110530a6032f0c032e13
032d2c3a052dfa032c1525052c3a032b64032a640329fe0328150327171105271e0326200325
1e0324231105402b241e0323110322000d0522fa03210f032140042014031f0a031e1e031d1c
19051d25031c0f13051c19031cb801004091041b0d031a194b051a7d0319011105194b0318fe
031711031615250516fa031501110515250314640313110312fe031101110511fe031064030f
0e10050f13030fc0040e10030e80040d0111050dfa030c32030b0a0d050b16030b80040a0d03
0a400409fe0308fe0307fe0306050a0506fe03050a0305400404fa030364030201110502fe03
01000d05011103000d0301b80164858d012b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b002b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b1d0000>
] def
FontName currentdict end definefont pop
%%Page: 1 1
%%BeginPageSetup
%%PageBoundingBox: 0 0 729 467
%%EndPageSetup
q
0 0 1 rg
BT
32 0 0 32 665.866135 266.844329 Tm
/f-0-0 1 Tf
[<0102>-1<03>]TJ
16 0 0 16 720.110429 262.96486 Tm
<04>Tj
0.00688881 1.593486 Td
<05>Tj
ET
0 g
2.4 w
0 J
0 j
[] 0.0 d
4 M q 1 0 0 -1 0 466.009949 cm
50.02 94.457 m 368.023 94.457 l 368.562 94.457 369 94.891 369 95.43 c
369 413.023 l 369 413.562 368.562 413.996 368.023 413.996 c 50.02
413.996 l 49.48 413.996 49.047 413.562 49.047 413.023 c 49.047 95.43 l
49.047 94.891 49.48 94.457 50.02 94.457 c h
50.02 94.457 m S Q
q 1 0 0 -1 0 466.009949 cm
209.086 93.41 m 208.184 415.445 l S Q
q 1 0 0 -1 0 466.009949 cm
49.086 254.016 m 369.086 254.016 l S Q
[ 9.6 2.4] 0 d
q 1 0 0 -1 0 466.009949 cm
130.113 46.016 m 129.086 464.238 l S Q
0.501961 0 0.501961 rg
0 291.994 m 417.086 291.276 l f*
0 g
[ 9.6 2.4] 0 d
q 1 0 0 -1 0 466.009949 cm
0 174.016 m 417.086 174.734 l S Q
[ 9.6 2.4] 0 d
q 1 0 0 -1 0 466.009949 cm
1.809 334.016 m 418.895 334.734 l S Q
[ 9.6 2.4] 0 d
q 1 0 0 -1 0 466.009949 cm
291 46.016 m 289.969 464.238 l S Q
BT
19.2 0 0 19.2 19.205015 409.065616 Tm
/f-0-0 1 Tf
[<06>-1<07>-1<0809>-1<0a010b>]TJ
6.543517 1.419601 Td
[<010a02>-1<0c0d>-1<0e0f10>-1<1108>-1<06>-1<12>1<08>-1<090a01>-1<0b>]TJ
ET
[] 0.0 d
q 1 0 0 -1 0 466.009949 cm
63.695 64.395 m 83.52 89.02 l S Q
77.5 384.467 m 70.75 385.197 l 85.027 375.119 l 78.23 391.217 l 77.5
384.467 l h
77.5 384.467 m f*
0.934725 w
q -0.805073 1 1 0.805073 0 466.009949 cm
-87.332 7.191 m -83.592 3.452 l -96.681 7.192 l -83.594 10.931 l
-87.332 7.191 l h
-87.332 7.191 m S Q
2.4 w
q 1 0 0 -1 0 466.009949 cm
244.809 35.773 m 281.629 73.781 l S Q
274.949 399.123 m 268.164 399.229 l 283.301 390.502 l 275.059 405.908 l
274.949 399.123 l h
274.949 399.123 m f*
0.861902 w
q -0.968718 1 1 0.968718 0 466.009949 cm
-171.911 108.416 m -168.466 104.968 l -180.532 108.416 l -168.465
111.863 l -171.911 108.416 l h
-171.911 108.416 m S Q
221.195 212.588 m 221.195 206.6 216.34 201.744 210.352 201.744 c
204.363 201.744 199.508 206.6 199.508 212.588 c 199.508 218.576 204.363
223.428 210.352 223.428 c 216.34 223.428 221.195 218.576 221.195
212.588 c h
221.195 212.588 m f
2.4 w
q 1 0 0 -1 0 466.009949 cm
221.195 253.422 m 221.195 259.41 216.34 264.266 210.352 264.266 c
204.363 264.266 199.508 259.41 199.508 253.422 c 199.508 247.434
204.363 242.582 210.352 242.582 c 216.34 242.582 221.195 247.434
221.195 253.422 c h
221.195 253.422 m S Q
BT
19.2 0 0 19.2 144.230569 228.768905 Tm
/f-0-0 1 Tf
<0d0c0e0a0804>Tj
32 0 0 32 379.681166 180.234689 Tm
<07>Tj
16 0 0 16 399.801082 177.224561 Tm
<05>Tj
ET
6.4 w
q 1 0 0 -1 0 466.009949 cm
211.324 254.969 m 368.77 254.969 l 369.309 254.969 369.742 255.406
369.742 255.945 c 369.742 412.305 l 369.742 412.844 369.309 413.277
368.77 413.277 c 211.324 413.277 l 210.785 413.277 210.352 412.844
210.352 412.305 c 210.352 255.945 l 210.352 255.406 210.785 254.969
211.324 254.969 c h
211.324 254.969 m S Q
0 0 1 rg
q 1 0 0 -1 0 466.009949 cm
130.613 174.734 m 288.055 174.734 l 288.594 174.734 289.031 175.168
289.031 175.707 c 289.031 332.066 l 289.031 332.605 288.594 333.039
288.055 333.039 c 130.613 333.039 l 130.074 333.039 129.637 332.605
129.637 332.066 c 129.637 175.707 l 129.637 175.168 130.074 174.734
130.613 174.734 c h
130.613 174.734 m S Q
BT
32 0 0 32 297.491598 260.886857 Tm
/f-0-0 1 Tf
<13>Tj
16 0 0 16 319.104642 257.007388 Tm
<04>Tj
ET
0 g
BT
32 0 0 32 671.745798 163.993741 Tm
/f-0-0 1 Tf
<07>Tj
16 0 0 16 691.865714 160.983612 Tm
<05>Tj
ET
0 0 1 rg
2.20579 w
[ 8.82316 2.20579] 0 d
q 1 0 0 -1 0 466.009949 cm
471.742 364.75 m 687.895 364.75 l S Q
2.277487 w
[ 9.109946 2.277487] 0 d
q 1 0 0 -1 0 466.009949 cm
577.023 256.781 m 578.254 465.332 l S Q
0 g
6.4 w
[] 0.0 d
q 1 0 0 -1 0 466.009949 cm
501.945 283.633 m 659.391 283.633 l 659.93 283.633 660.363 284.066
660.363 284.605 c 660.363 440.969 l 660.363 441.508 659.93 441.941
659.391 441.941 c 501.945 441.941 l 501.406 441.941 500.973 441.508
500.973 440.969 c 500.973 284.605 l 500.973 284.066 501.406 283.633
501.945 283.633 c h
501.945 283.633 m S Q
512.004 26.897 m 512.004 20.908 507.148 16.053 501.16 16.053 c 495.172
16.053 490.316 20.908 490.316 26.897 c 490.316 32.885 495.172 37.74
501.16 37.74 c 507.148 37.74 512.004 32.885 512.004 26.897 c h
512.004 26.897 m f
2.4 w
q 1 0 0 -1 0 466.009949 cm
512.004 439.113 m 512.004 445.102 507.148 449.957 501.16 449.957 c
495.172 449.957 490.316 445.102 490.316 439.113 c 490.316 433.125
495.172 428.27 501.16 428.27 c 507.148 428.27 512.004 433.125 512.004
439.113 c h
512.004 439.113 m S Q
667.41 25.815 m 667.41 19.826 662.559 14.971 656.57 14.971 c 650.582
14.971 645.727 19.826 645.727 25.815 c 645.727 31.803 650.582 36.654
656.57 36.654 c 662.559 36.654 667.41 31.803 667.41 25.815 c h
667.41 25.815 m f
q 1 0 0 -1 0 466.009949 cm
667.41 440.195 m 667.41 446.184 662.559 451.039 656.57 451.039 c
650.582 451.039 645.727 446.184 645.727 440.195 c 645.727 434.207
650.582 429.355 656.57 429.355 c 662.559 429.355 667.41 434.207 667.41
440.195 c h
667.41 440.195 m S Q
669.012 183.549 m 669.012 177.561 664.156 172.709 658.168 172.709 c
652.18 172.709 647.324 177.561 647.324 183.549 c 647.324 189.537 652.18
194.393 658.168 194.393 c 664.156 194.393 669.012 189.537 669.012
183.549 c h
669.012 183.549 m f
q 1 0 0 -1 0 466.009949 cm
669.012 282.461 m 669.012 288.449 664.156 293.301 658.168 293.301 c
652.18 293.301 647.324 288.449 647.324 282.461 c 647.324 276.473 652.18
271.617 658.168 271.617 c 664.156 271.617 669.012 276.473 669.012
282.461 c h
669.012 282.461 m S Q
511.273 181.951 m 511.273 175.963 506.418 171.108 500.43 171.108 c
494.441 171.108 489.586 175.963 489.586 181.951 c 489.586 187.94
494.441 192.795 500.43 192.795 c 506.418 192.795 511.273 187.94 511.273
181.951 c h
511.273 181.951 m f
q 1 0 0 -1 0 466.009949 cm
511.273 284.059 m 511.273 290.047 506.418 294.902 500.43 294.902 c
494.441 294.902 489.586 290.047 489.586 284.059 c 489.586 278.07
494.441 273.215 500.43 273.215 c 506.418 273.215 511.273 278.07 511.273
284.059 c h
511.273 284.059 m S Q
0 0 1 rg
6.4 w
q 1 0 0 -1 0 466.009949 cm
498.059 48.957 m 655.5 48.957 l 656.039 48.957 656.477 49.391 656.477
49.93 c 656.477 206.289 l 656.477 206.828 656.039 207.262 655.5 207.262
c 498.059 207.262 l 497.52 207.262 497.086 206.828 497.086 206.289 c
497.086 49.93 l 497.086 49.391 497.52 48.957 498.059 48.957 c h
498.059 48.957 m S Q
BT
32 0 0 32 670.390801 387.355153 Tm
/f-0-0 1 Tf
<13>Tj
16 0 0 16 692.003845 383.475684 Tm
<04>Tj
ET
0 g
2.218275 w
q 1 0 0 -1 0 466.009949 cm
470.402 126.016 m 689.012 126.016 l S Q
2.4 w
q 1 0 0 -1 0 466.009949 cm
577.926 28.355 m 575.758 233.285 l S Q
BT
19.2 0 0 19.2 554.028067 348.251023 Tm
/f-0-0 1 Tf
<04>Tj
ET
0 0.639216 1 rg
578.871 339.424 m 652.883 339.424 l 653.406 339.424 653.828 339.002
653.828 338.479 c 653.828 262.377 l 653.828 261.854 653.406 261.432
652.883 261.432 c 578.871 261.432 l 578.348 261.432 577.926 261.854
577.926 262.377 c 577.926 338.479 l 577.926 339.002 578.348 339.424
578.871 339.424 c h
578.871 339.424 m f
0 g
586.602 339.994 m 586.602 334.006 581.746 329.151 575.758 329.151 c
569.77 329.151 564.914 334.006 564.914 339.994 c 564.914 345.983 569.77
350.838 575.758 350.838 c 581.746 350.838 586.602 345.983 586.602
339.994 c h
586.602 339.994 m f
q 1 0 0 -1 0 466.009949 cm
586.602 126.016 m 586.602 132.004 581.746 136.859 575.758 136.859 c
569.77 136.859 564.914 132.004 564.914 126.016 c 564.914 120.027 569.77
115.172 575.758 115.172 c 581.746 115.172 586.602 120.027 586.602
126.016 c h
586.602 126.016 m S Q
BT
19.2 0 0 19.2 477.549915 188.565745 Tm
/f-0-0 1 Tf
<04>Tj
-0.0502762 -9.613125 Td
<14>Tj
ET
0 0 1 rg
6.4 w
q 1 0 0 -1 0 466.009949 cm
503.68 364.484 m 577.41 364.484 l S Q
0 g
BT
32 0 0 32 442.393665 52.940609 Tm
/f-0-0 1 Tf
<15>Tj
16 0 0 16 460.287959 49.061139 Tm
<0414>Tj
-0.154439 1.593485 Td
<05>Tj
ET
0 0 1 rg
BT
32 0 0 32 440.331461 132.529837 Tm
/f-0-0 1 Tf
<0a>Tj
16 0 0 16 460.638255 128.650368 Tm
<0414>Tj
-0.154439 1.593485 Td
<05>Tj
ET
0 g
2.4 w
q 1 0 0 -1 0 466.009949 cm
474.098 331.953 m 478.16 330.844 484.367 332.91 489.281 334.016 c
494.137 335.109 500.012 335.797 504.461 339.547 c 513.086 346.812
513.215 348.691 515.301 351.473 c 517.215 354.02 514.492 355.82 515.301
359.062 c S Q
512.973 116.26 m 507.152 119.752 l 515.883 104.619 l 516.465 122.08 l
512.973 116.26 l h
512.973 116.26 m f*
1.164171 w
q -0.250001 1 1 0.250001 0 466.009949 cm
-449.876 400.503 m -445.22 395.847 l -461.517 400.503 l -445.22 405.16
l -449.876 400.503 l h
-449.876 400.503 m S Q
3.037832 w
q 1 0 0 -1 0 466.009949 cm
472.02 406.277 m 477.867 407.375 486.641 404.832 493.605 403.414 c
500.492 402.008 508.848 401.023 515.027 396.664 c 527.008 388.203
527.105 386.094 529.957 382.902 c 532.566 379.977 528.598 378.059
529.602 374.395 c S Q
526.383 79.897 m 530.633 72.428 l 530.406 94.545 l 518.914 75.651 l
526.383 79.897 l h
526.383 79.897 m f*
1.464627 w
q -0.274787 -1 -1 0.274787 0 466.009949 cm
224.517 -588.077 m 230.376 -593.937 l 209.869 -588.076 l 230.374
-582.218 l 224.517 -588.077 l h
224.517 -588.077 m S Q
544.824 102.479 m 544.824 98.002 541.68 94.373 537.797 94.373 c 533.918
94.373 530.77 98.002 530.77 102.479 c 530.77 106.959 533.918 110.588
537.797 110.588 c 541.68 110.588 544.824 106.959 544.824 102.479 c h
544.824 102.479 m f
BT
19.2 0 0 19.2 10.90625 451.441199 Tm
/f-0-0 1 Tf
<0f16>Tj
22.82549 -0.0994533 Td
<1716>Tj
0.144399 -12.367117 Td
<0216>Tj
ET
3.162158 w
q 1 0 0 -1 0 466.009949 cm
537.418 398.488 m 537.27 370.441 l 537.27 370.441 l 537.27 370.441 l
537.27 370.441 l S Q
537.395 71.315 m 534.219 74.463 l 537.438 63.412 l 540.543 74.494 l
537.395 71.315 l h
537.395 71.315 m f*
0.790529 w
q -0.00521464 1 1 0.00521464 0 466.009949 cm
-397.487 535.322 m -394.322 532.163 l -405.389 535.324 l -394.324
538.487 l -397.487 535.322 l h
-397.487 535.322 m S Q
BT
32 0 0 32 546.004061 58.040995 Tm
/f-1-0 1 Tf
<01>Tj
16 0 0 16 565.835855 54.161524 Tm
/f-0-0 1 Tf
<0414>Tj
-0.154439 1.593485 Td
<05>Tj
ET
0 0 1 rg
BT
32 0 0 32 532.228949 137.155305 Tm
/f-0-0 1 Tf
<17>Tj
16 0 0 16 552.404493 131.675836 Tm
<04>Tj
0.00688881 1.593485 Td
<05>Tj
ET
Q
showpage
%%Trailer
count op_count sub {pop} repeat
countdictstack dict_count sub {end} repeat
cairo_eps_state restore
%%EOF

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,931 @@
%!PS-Adobe-3.0 EPSF-3.0
%%Creator: cairo 1.10.2 (http://cairographics.org)
%%CreationDate: Thu Jun 21 11:29:49 2012
%%Pages: 1
%%BoundingBox: 0 -1 370 203
%%DocumentData: Clean7Bit
%%LanguageLevel: 2
%%EndComments
%%BeginProlog
/cairo_eps_state save def
/dict_count countdictstack def
/op_count count 1 sub def
userdict begin
/q { gsave } bind def
/Q { grestore } bind def
/cm { 6 array astore concat } bind def
/w { setlinewidth } bind def
/J { setlinecap } bind def
/j { setlinejoin } bind def
/M { setmiterlimit } bind def
/d { setdash } bind def
/m { moveto } bind def
/l { lineto } bind def
/c { curveto } bind def
/h { closepath } bind def
/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto
0 exch rlineto 0 rlineto closepath } bind def
/S { stroke } bind def
/f { fill } bind def
/f* { eofill } bind def
/n { newpath } bind def
/W { clip } bind def
/W* { eoclip } bind def
/BT { } bind def
/ET { } bind def
/pdfmark where { pop globaldict /?pdfmark /exec load put }
{ globaldict begin /?pdfmark /pop load def /pdfmark
/cleartomark load def end } ifelse
/BDC { mark 3 1 roll /BDC pdfmark } bind def
/EMC { mark /EMC pdfmark } bind def
/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def
/Tj { show currentpoint cairo_store_point } bind def
/TJ {
{
dup
type /stringtype eq
{ show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse
} forall
currentpoint cairo_store_point
} bind def
/cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore
cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def
/Tf { pop /cairo_font exch def /cairo_font_matrix where
{ pop cairo_selectfont } if } bind def
/Td { matrix translate cairo_font_matrix matrix concatmatrix dup
/cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point
/cairo_font where { pop cairo_selectfont } if } bind def
/Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def
cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def
/g { setgray } bind def
/rg { setrgbcolor } bind def
/d1 { setcachedevice } bind def
%%EndProlog
%!FontType1-1.1 f-0-0 1.0
11 dict begin
/FontName /f-0-0 def
/PaintType 0 def
/FontType 1 def
/FontMatrix [0.001 0 0 0.001 0 0] readonly def
/FontBBox {0 -217 824 729 } readonly def
/Encoding 256 array
0 1 255 {1 index exch /.notdef put} for
dup 1 /uni0061 put
dup 2 /uni0070 put
dup 3 /uni006C put
dup 4 /uni0069 put
dup 5 /uni0063 put
dup 6 /uni0074 put
dup 7 /uni006F put
dup 8 /uni006E put
dup 9 /uni0073 put
dup 10 /uni0065 put
dup 11 /uni0078 put
dup 12 /uni0072 put
dup 13 /uni0020 put
dup 14 /uni0067 put
dup 15 /uni0064 put
dup 16 /uni006D put
dup 17 /uni0075 put
dup 18 /uni007A put
readonly def
currentdict end
currentfile eexec
f983ef0097ece636fb4a96c74d26ab84185f6dfa4a16a7a1c27bbe3f1156aea698df336d20b467
b10e7f33846656653c5ac6962759d3056cbdb3190bac614b984bf5a132dc418192443014ba63de
800d392b6fea026574bb2535fd7bb5338f35bf15a88ea328fdaa49670c7852e3d060f3c5d6b07f
2ef6d0f22646c5d18e19a2ae3ee120390f6dd96f76dcf1e127de5e9299077a00c17c0d71e36e5b
9d5ec58fceda57739a6a4214d4b79d6c48d2784b60c320323c7acddddf34db833cac0cf109f799
69d114a330d372e5c978a66acc84e3fe5557f6240856a013ffaa0199444e5c5036f775eba4a5c5
8cde66cf604b9aca2178431127b8a1ff7ed633a65c04600af5f573483112251caf31d0c7c7e1a8
decc942f4bccae86153efd43475966e5202fd074417312c7ef5f32a8a3c64c0d31e6cf05a8395b
2ec3c61df5842085ae3dcacc966e269bbdacf7237c70186a824529500005ed5b5b73afe50c2f0b
5a121454a496ea47e14b6787f14162b260cb91c49ed9b471f2b40180a9a92eaa9e7dca9bf280f0
e1d53c47d8125db101643e7fa0fa3870458b1c6cd3d3acf90cc884cc3593f15ae6c9fc1fbebac1
824d9f9824520c846901fa8051e658bd15f58b60a6fcd54b666ca1212d3e0f80252798f78a57c2
502e12149e84672d18956d90f23b04e67d98f032acc84557fd8395fb01b83624fab41ebd5b80fe
211c6b3af6bef8a6cdc78d5a37f1be2b7f96f95f51c4ab3301d6037bf4beb7fd5733829289ae7f
892192eab10c172ae6d2c711ca395cca4c94a82a5318c4d3e6f1cd231eff43967e08ae53a44e37
955ff6a1ef639cbe97451c6d457f272c62bc855f0bfec5223be6559b04935ce7d117b05dd7c82c
9358e68434fc4dd88b34800c0060e8df0224b5f495326188e4727070edf06104b9005eda4790ad
1ac793bd28fc607fcd8fb0777e49187363881eadabe6b090aa43b089252d3e58badf380cc8cd82
3fb2cafa68acbb4a71327adf1891447add56fb1730748076ff2a28e59a8d0aa88002ff1e642048
4a5b173d2f1a80ef8e9408163f50cbd4804d82a8c9fe69d41f146bd85d1f001a729f1973ffb1b9
69ba898d50fa879ad2fe472a9910f94f2d852720422ea1ab2ef93bcb21a03fa3be7810ab3cb799
07c5c6e4ef9c5fea7e05230472f7a5f26ae58b5f92acb881efa0c24ee81a7db41ffa3d47f73ab9
32fcd737d76bf4a4dae8c14380d410042e8acb5011b2c6a382da7633bf7b515bd20b5f3a15f949
a7c535bd506b2bb05284a3433b1a6289a911a67415e95b1d2cc9c27c8e4e65e43ef94371b42657
bd767e5d26a6e5351c50d8a9722470cf0db64bf5cf5bdaa7070c6785297c59324f75337371425d
29fefc41b7973876cacefd511eb15fc59360792780823d00afb427535f9925211a0553b47ae20e
0cdeff1dee1fea484222c476cb70233e4f0d3658bd12a981e5ceb706280f4b2ed7d8d6f630a8d7
fbcb3bd242f31ce80548a8d4a39cbf5e9b87cd9136afb3b32b0e0dc53d4c45e243ace71640f6b3
9ed13457605806edb2ad5b5cc894aa8aeca482fe6c23c17787c412e7273dec43ba61d6e335fcc5
dd76227e6cc0378bdba487821a7550ad8635ff2766f1f78bf993a32447b744d70192bf49bb126b
d4f5472a0b7d7e12ac9de080246182af4b1ba5e2e55d3af38fd85fb3785dddbfdccd5309446833
f5b8e384b8feea425e21919f2b4cc5e9a0613e6ac7d8510d2ddd51b266006dc5c7268d9bb66d5c
553a2c5c1b19128088bd0dba462d42427acdd6b7070c35211799b146fc0b8df474eea6cac619a2
4201f5e3b4c0ebf1195492e46b91d8aa348cee1b46d5e42b1e9e793b8be3aa42b55059a7af1393
e7a10637c75f7fb0c6ed0af276044850bfe6046baff7cb7bb0ced50cb85a43f018615af02c5872
4cdb27db6bbd81b3371665def0dd5c2dd4cd992c987de6000fe3b4c31413f5d6baa34bd9ce28d3
e8c85f175704e10ac7f8c9c2068b7d7d52bb13f1cfb74fb186247198419d6e00b6d5d13fcb241c
9e6848a0f78693f8e7d2767daf4136288404eeb66ee530d49019c64e3fb85930b389c6144d35cb
fe58833a4c27af41585b5b5737fe783798f33d0fed960c4009c9ba3b87eb0a3130a43b822ca070
a0b1c65ccb88ebe42d2c3fe3e1df54ac7d4c17a4f868be1b9f69ae83ce67ba202178c1532eb2ff
7934b597318ebfb174afca3561f7fee2840b7309fd39b4341967f584a9326975e6df200e3df424
9178e08ced5f50df68bfd1dc610a29a87b8b4618eda2f335bf5917fdb23775ee6006d5c6ca347f
d9923f993f5cd894e2a62689accdba180e1d734641e560e761d1e5c4df99fd8a37efda8abc9d20
eb30982380e4a81146191c13e1d8d70a7b180566d887c411a4c185b8781e31400554676ef69899
e17e73950096eac1ad2a3726f3dd790470712b81db0d69b27636a71327e7ad401aeacc8fa00e43
ccb1e50a090af5feaad4ed6c7e46a355cf84a8bfd8f35bbb19d6d5c874b46f9fa932ecaed3501d
353b8708523f5b10da00ae2fca7daa0d237adcc1a9ce90867ccea1a31876a6d3dec73bf061207f
edd7bd2a7675571e283114d22e27ebb78a56e588eda28d35d73282d452e61d2c082b22723131d0
6c1a4aff0dbd3f0729ce32148b94b63f0ea1063f41177b0731a4e4989087032f21eef4b47eda0a
deb61fd53bc777125f0f006cc922c1a87ca41ff63d1a6902426888e381e43f4c195b813f7c1c42
09088a3a1cf40d6ec9941d17807c5de5a1d822983555930ca1b0b7f9f678890b8de836f9b079f4
b352eb7934697b04a05b67454d3e12c751674c2f93c5d00221ac7b8acf465d957c7feed8c73c33
90fef823fd2b6513db81a108436f87bdd8a2c6221b827605ffbc7801d3f844c559ef8dc741ba58
6f7398e1f005b60609c39913412b6cd87b95ac66adecc780324c115b2108fb45da39be32ae87bf
23ac353f1cead52535fdfa07fe94011a0b3bbb13be10b8a698be4e16271cd0ce324cd29bb1d25c
9d63f253d22d12b57440c32548586bf84c1edbf41a969db0dfa2162933d19d244440164ba4bd70
cafd4d3be81c19caa2bbc7684cb5873ab2e3e2570e79f8b3f2666f8d40e8c30572ad06d6444f3e
a50a9ea6ffe1346e72a04758b8c787a9fd25dd55a9fb51bcb081a16cb44b43914ae8b749c6527b
e6a1df291c2d386aa4ba017628193c803a6d28949c0128e998dd643280138b9a8e9483aac32d5a
b8d7059abb22f711dd1282ecf3399f07b6d58e9a18de37195ae4a0106ca1576bad424ff70ba59f
6f8da327a7e951d8be7a6a616c13b968d6810590c6ee39753aa54ad8ea32331ef2edf4eadebc42
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
cleartomark
%!FontType1-1.1 f-1-0 1.0
11 dict begin
/FontName /f-1-0 def
/PaintType 0 def
/FontType 1 def
/FontMatrix [0.001 0 0 0.001 0 0] readonly def
/FontBBox {14 -217 762 732 } readonly def
/Encoding 256 array
0 1 255 {1 index exch /.notdef put} for
dup 1 /uni006C put
dup 2 /uni006F put
dup 3 /uni0063 put
dup 4 /uni0061 put
dup 5 /uni0066 put
dup 6 /uni0075 put
dup 7 /uni006E put
dup 8 /uni0074 put
dup 9 /uni0069 put
dup 10 /uni0073 put
dup 11 /uni0067 put
dup 12 /uni0072 put
dup 13 /uni0064 put
dup 14 /uni0070 put
dup 15 /uni0065 put
dup 16 /uni0062 put
dup 17 /uni006D put
readonly def
currentdict end
currentfile eexec
f983ef0097ece636fb4a96c74d26ab84185f6dfa4a16a7a1c27bbe3f1156aea698df336d20b467
b10e7f33846656653c5ac6962759d3056cbdb3190bac614b984bf5a132dc418192443014ba63de
800d392b6fea026574bb2535fd7bb5338f35bf15a88ea328fdaa49670c7852e3d060f3c5d6b07f
2ef6d0f22646c5d18e19a2ae3ee120390f6dd96f76dcf1e127de5e9299077a00c17c0d71e36e5b
9d5ec58fceda57739a6a4214d4b79d6c48d2784b60c320323c7acddddf34db833cac0cf109f799
69d114a330d372e5c978a66acc84e3fe5557f6240856a013ffaa0199444e5c5036f775eba4a5c5
8cde66cf604b9aca2178431127b8a1ff7ed633a65c04600af5f573483112251cacaf9a06b6a42b
0a4043938e24416c9f587b348e8ab9cce1d9dd4807509a1c1b397781329867de3ca9f303cfbffa
a130d475ee35ec2251bc9584bd0404a85f27405bc083207d3fffce07e03331d584eeb7bd31eee5
25f9183a8a41a0127d7e779ebcfed7027d94228df77c6e9e5b6c942061c9a19b698a2641ce7bf1
91281cf95e724ce492b1d21ef000c582487da7f6d539b8c411eebd07899b75f9bfa0809d462ab9
cce2cb32c530cde4c42266720372cd239af22523ae47d06bf8cc3596bc1eef98a412c44b1222f9
ca897cafa3bf6b64772ce9dd6f35806aa5b948ee4cac9456ae50c22c4abe9ca06a9bfb5450f31e
c16472c2a64eb6233dc84f6f40a88b7d3f7eebf236b4d6f4854ea206979c79dc5626164cb0a755
c0814108344168ca6ff0998bdeddb3103855d7076b8e57fb68f7569267a11c79fc1096d1ab8b13
df8ec589de12837c1f4809ab165de160449d694d6f42ed4ff2afbcd03f6b99ef40051072a173dc
983f7656eb7d84b6dc9d4b80665948141ca2ff9552489b219753772484f740f3037707e42a5cbb
288209290082c5f04a01d7c731dfd345961c2e1b7322579f5ab0bae6855810669ebbbc1fe995a4
009443e1fee246f72bc4112ddbab213c1aaee0f050b1d439156931e5c2d41b381f9dbd47de627e
3b9dc8863e5dfe89eaa16c8f1f31c7e17fcfe3fc0bddae7520868c60dcf4e17cae3f56815c0ac3
611010eb9e134112c87d43068619cd461972da89e5143afd979c826cc14d479c6f4123ea81b849
8e92a4205f2e86c0de68682247bee6ff1a4ed0b7e08d06a2c96ebd837e73d613f568eac6eb18a3
b89068df3cc092116ef03514ff236df49bd9d9502491921a4aa204e89ca06eb49856680f86e7a7
0f9b17273fa93e7082ebfee9a25821dee4186926592e0914070c2dab258e547e3955e163377588
8d2e2e70be7d7c47c7fc65bc4861d8695661ac3ef1abd5f46df6240307eab8ddd0d20f24e06fce
bddbfdff1500251740c8b0f3ad8960612749d5774fdf3912f91d0402ecd105a169ac0997003ec5
cf0ace9ee4957975ffee48605df13c089139be632ce4b6ef62d2ff9e10f40cfd07be0f82c9cd72
b1ef70082b86b969755b5f88a24cc3bee2abe90689adf1041b37cf0a6dc73dec3dcbfe6ea14099
9c45bf11d7e0b65e32a8eea602f1be2ee0c60ea7489afdda08edd1e25d14a0bfe6f751a7d90139
b8ecbdc685a8eb920fba25f075093ad0a7cfeb898a77914282e805f5264b9f469a6c9d76c4b5ce
77f3940810dadad376e412a8a385546f7dd84b53467ab0b45b5f98e378d70c97cc9e7a0ad30aa6
e235bf486e99bf1608b7f6b651bb18c32cef510ff88431e592739be53c76d8adef804e8e275007
500d25bdb5381ba8a74980f0a6ad2fb4a1120eeb299c276199f64ff9b45a1406d3915d690347f8
31935b3227bf87b29c35f0e91d07fca44a08a195a7951a35b6d83245e97f3f4db48e3576f0a42b
706c0ef9a95e118c6af7274f33f21275eda22e3a3053fe5d7244004f71253dafb15fe53a1f29f6
7c283df5ffc02877d98b4052461684a88e0bd0adaac3e18654bcbff930a57c99b2b48aa607d5bd
e600efe3f9e6d6626cc108f47d2fe14a91c1e10bc6fa92d3a711eb1066dc378b0475945a077965
4e1c3eb9b5fcb4e3ed1e8225c47d281bff10ee6df45997b77365cf2b4209ba2280bfeb270eb84e
ac07a6fc476acc50197e057bf10e8f048afeda4ad8d82ef873abffd8c2e9dc3901d498f65dddf1
92d9e87a36dc5d76a3be7883f9237be83b1e7a5aca3444a8a70881926750c054b88827795542b6
924a1c7fa639434334b8c23b409b7b37d22bb471ec58a3d1ec9bb56b240b75200e53bc35ec277a
b8ceb37cf1872c651dc541075f606819f3c162547c332b04e669ec2f414b2af8994becc206131e
1bacfb99edba3a1f35404393ae15fe866f5836a00a95ea57ee2a4a55d55380a03ef12530d6e3ad
d0bbbdf4cd0287a3c7af7f378396591c7eb2136724ce97b4c11f2dcff55a0052c08e9165eec865
ed805dc5968dbd605591067d9db20a9da3359ef101aa869cc40ea683beb2965ce9c5d17655cde3
7b818483c9e9bea8e6b97a927750d73308db4eb5ece596316c1fcc57968fb3b4240ec5c86022a2
2caa207be1c96404ca7edc735a574122678ac58404d47f29c66a6f5df1fc619ad0cd2c0aa32cec
391bdec3bce8528e95604dbf43b0954ccb486d81c47a3e29590d0e967e0ef1fee344d2192f9c94
ec14034796295a63458308e8cfb67ecd40fb5dca4c9895eadf191fd37c59ef5f44f78cff4c3d79
1d6a8b21197477e1a5138ddc12bad7635d114e02e038adbe9ab2a1dbf6155270660d8de8694cf1
08bca1daef26b9973e31e25bf81e5f28eee5d07ff87fccafe30cc51754e5a1fbf03501cd31aa9a
a223faf9c031017ae45a5c1de674953f97e60c92a792c706acbd6a60320e1f6b8b2020a6ad53df
e832fdcce63cb15a4fad891db8a844731829dc22d630e6199c1d64043f7fd32908ae7c5ad0a636
3875ff6eb4e87d7c473b9eaf00d3b193a895cc62c31633807cf1211ab8332a22f720e442bf32a4
af2b647694d527a5aa02cc4e0f119c4bb7d93abb7ad6259943d058ce3f340591a3bf89a2e8dc51
4d6a9fcb00e577c7027553f44806b01d5d3349b6f868ec6d9488f3b458b9d3b7cb3786f78bec53
2569a306ea15c856c36017297a8f0a86c6fb6e7a390cbbd5b398e1fa4a8f29aeb455c491c30257
10893969d559ca61b7a19494161f163d0349acaf3a272528e4fe7e75674b9a720fca53cd02d1c6
62f766cd5df5fcc54af862b3a313673662751c7f10ed1af61f38802ef6c072cb040aabd2c271be
e864597dc0707748eab4b4ddc2a7874bbf61488f465a4095aedaf6f8d692f0996d29edaca0e439
f34a9d72d030b1635733d05ac333649d4e24f6328b4efb4578ac1c2a8b9a15009774aaaf66a60000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
cleartomark
%%Page: 1 1
%%BeginPageSetup
%%PageBoundingBox: 0 -1 370 203
%%EndPageSetup
q 0 -1 370 204 rectclip q
0 202.46 370 -203 re W n
0.952941 g
13.602 170.405 m 355.996 170.405 l 362.645 170.405 368 165.053 368
158.401 c 368 13.608 l 368 6.96 362.645 1.604 355.996 1.604 c 13.602
1.604 l 6.953 1.604 1.598 6.96 1.598 13.608 c 1.598 158.401 l 1.598
165.053 6.953 170.405 13.602 170.405 c h
13.602 170.405 m f*
0.792157 g
3.2 w
0 J
0 j
[] 0.0 d
4 M q 1 0 0 -1 0 202.459579 cm
13.602 32.055 m 355.996 32.055 l 362.645 32.055 368 37.406 368 44.059 c
368 188.852 l 368 195.5 362.645 200.855 355.996 200.855 c 13.602
200.855 l 6.953 200.855 1.598 195.5 1.598 188.852 c 1.598 44.059 l
1.598 37.406 6.953 32.055 13.602 32.055 c h
13.602 32.055 m S Q
0.909804 0.556863 0.247059 rg
37.422 153.022 m 33.551 152.014 28.281 159.635 26.195 163.042 c 23.191
167.956 17.285 177.87 18.812 183.424 c 19.875 187.276 29.109 188.03
33.105 188.131 c 38.859 188.28 50.402 188.436 54.445 184.338 c 57.254
181.491 53.289 173.116 51.379 169.604 c 48.629 164.546 42.992 154.475
37.422 153.022 c h
37.422 153.022 m f
0.721569 0.376471 0.0588235 rg
q 1 0 0 -1 0 202.459579 cm
37.422 49.438 m 33.551 50.445 28.281 42.824 26.195 39.418 c 23.191
34.504 17.285 24.59 18.812 19.035 c 19.875 15.184 29.109 14.43 33.105
14.328 c 38.859 14.18 50.402 14.023 54.445 18.121 c 57.254 20.969
53.289 29.344 51.379 32.855 c 48.629 37.914 42.992 47.984 37.422 49.438
c h
37.422 49.438 m S Q
0.909804 0.556863 0.247059 rg
168.75 153.022 m 164.883 152.014 159.613 159.635 157.527 163.042 c
154.52 167.956 148.613 177.87 150.141 183.424 c 151.203 187.276 160.438
188.03 164.434 188.131 c 170.191 188.28 181.73 188.436 185.773 184.338
c 188.582 181.491 184.617 173.116 182.707 169.604 c 179.957 164.546
174.324 154.475 168.75 153.022 c h
168.75 153.022 m f
0.721569 0.376471 0.0588235 rg
q 1 0 0 -1 0 202.459579 cm
168.75 49.438 m 164.883 50.445 159.613 42.824 157.527 39.418 c 154.52
34.504 148.613 24.59 150.141 19.035 c 151.203 15.184 160.438 14.43
164.434 14.328 c 170.191 14.18 181.73 14.023 185.773 18.121 c 188.582
20.969 184.617 29.344 182.707 32.855 c 179.957 37.914 174.324 47.984
168.75 49.438 c h
168.75 49.438 m S Q
0.909804 0.556863 0.247059 rg
124.973 153.022 m 121.105 152.014 115.836 159.635 113.75 163.042 c
110.742 167.956 104.836 177.87 106.367 183.424 c 107.426 187.276 116.66
188.03 120.656 188.131 c 126.414 188.28 137.953 188.436 142 184.338 c
144.805 181.491 140.84 173.116 138.93 169.604 c 136.18 164.546 130.547
154.475 124.973 153.022 c h
124.973 153.022 m f
0.721569 0.376471 0.0588235 rg
q 1 0 0 -1 0 202.459579 cm
124.973 49.438 m 121.105 50.445 115.836 42.824 113.75 39.418 c 110.742
34.504 104.836 24.59 106.367 19.035 c 107.426 15.184 116.66 14.43
120.656 14.328 c 126.414 14.18 137.953 14.023 142 18.121 c 144.805
20.969 140.84 29.344 138.93 32.855 c 136.18 37.914 130.547 47.984
124.973 49.438 c h
124.973 49.438 m S Q
0.909804 0.556863 0.247059 rg
81.195 153.022 m 77.328 152.014 72.059 159.635 69.973 163.042 c 66.965
167.956 61.062 177.87 62.59 183.424 c 63.652 187.276 72.887 188.03
76.883 188.131 c 82.637 188.28 94.18 188.436 98.223 184.338 c 101.031
181.491 97.066 173.116 95.156 169.604 c 92.402 164.546 86.77 154.475
81.195 153.022 c h
81.195 153.022 m f
0.721569 0.376471 0.0588235 rg
q 1 0 0 -1 0 202.459579 cm
81.195 49.438 m 77.328 50.445 72.059 42.824 69.973 39.418 c 66.965
34.504 61.062 24.59 62.59 19.035 c 63.652 15.184 72.887 14.43 76.883
14.328 c 82.637 14.18 94.18 14.023 98.223 18.121 c 101.031 20.969
97.066 29.344 95.156 32.855 c 92.402 37.914 86.77 47.984 81.195 49.438
c h
81.195 49.438 m S Q
0.909804 0.556863 0.247059 rg
202.836 170.561 m 202.836 168.983 201.559 167.702 199.98 167.702 c
198.402 167.702 197.121 168.983 197.121 170.561 c 197.121 172.139
198.402 173.417 199.98 173.417 c 201.559 173.417 202.836 172.139
202.836 170.561 c h
202.836 170.561 m f
0.721569 0.376471 0.0588235 rg
q 1 0 0 -1 0 202.459579 cm
202.836 31.898 m 202.836 33.477 201.559 34.758 199.98 34.758 c 198.402
34.758 197.121 33.477 197.121 31.898 c 197.121 30.32 198.402 29.043
199.98 29.043 c 201.559 29.043 202.836 30.32 202.836 31.898 c h
202.836 31.898 m S Q
0.909804 0.556863 0.247059 rg
213.406 170.561 m 213.406 168.983 212.129 167.702 210.551 167.702 c
208.973 167.702 207.691 168.983 207.691 170.561 c 207.691 172.139
208.973 173.417 210.551 173.417 c 212.129 173.417 213.406 172.139
213.406 170.561 c h
213.406 170.561 m f
0.721569 0.376471 0.0588235 rg
q 1 0 0 -1 0 202.459579 cm
213.406 31.898 m 213.406 33.477 212.129 34.758 210.551 34.758 c 208.973
34.758 207.691 33.477 207.691 31.898 c 207.691 30.32 208.973 29.043
210.551 29.043 c 212.129 29.043 213.406 30.32 213.406 31.898 c h
213.406 31.898 m S Q
0.909804 0.556863 0.247059 rg
223.98 170.561 m 223.98 168.983 222.699 167.702 221.121 167.702 c
219.543 167.702 218.266 168.983 218.266 170.561 c 218.266 172.139
219.543 173.417 221.121 173.417 c 222.699 173.417 223.98 172.139 223.98
170.561 c h
223.98 170.561 m f
0.721569 0.376471 0.0588235 rg
q 1 0 0 -1 0 202.459579 cm
223.98 31.898 m 223.98 33.477 222.699 34.758 221.121 34.758 c 219.543
34.758 218.266 33.477 218.266 31.898 c 218.266 30.32 219.543 29.043
221.121 29.043 c 222.699 29.043 223.98 30.32 223.98 31.898 c h
223.98 31.898 m S Q
0.196078 g
BT
11.2 0 0 11.2 17.560657 194.294779 Tm
/f-0-0 1 Tf
[<01>-1<02>6<02>15<03>16<04>21<05>9<01>18<06>15<04>20<07>29<08>15<09>]TJ
ET
0.905882 0.952941 1 rg
176.797 145.604 m 236 145.604 l 240.43 145.604 244 142.038 244 137.604
c 244 89.604 l 244 85.174 240.43 81.604 236 81.604 c 176.797 81.604 l
172.367 81.604 168.797 85.174 168.797 89.604 c 168.797 137.604 l
168.797 142.038 172.367 145.604 176.797 145.604 c h
176.797 145.604 m f*
0.690196 0.737255 0.894118 rg
q 1 0 0 -1 0 202.459579 cm
176.797 56.855 m 236 56.855 l 240.43 56.855 244 60.422 244 64.855 c 244
112.855 l 244 117.285 240.43 120.855 236 120.855 c 176.797 120.855 l
172.367 120.855 168.797 117.285 168.797 112.855 c 168.797 64.855 l
168.797 60.422 172.367 56.855 176.797 56.855 c h
176.797 56.855 m S Q
0.196078 g
BT
11.2 0 0 11.2 175.998181 129.605192 Tm
/f-0-0 1 Tf
[<0a>25<0b>9<06>9<0c>19<010d0e>10<0c04>16<0f>19<09>]TJ
ET
0.611765 0.678431 0.847059 rg
17.555 73.604 m 352 73.604 l 356.43 73.604 360 70.038 360 65.604 c 360
17.604 l 360 13.174 356.43 9.604 352 9.604 c 17.555 9.604 l 13.121
9.604 9.555 13.174 9.555 17.604 c 9.555 65.604 l 9.555 70.038 13.121
73.604 17.555 73.604 c h
17.555 73.604 m f*
0.266667 0.411765 0.721569 rg
q 1 0 0 -1 0 202.459579 cm
17.555 128.855 m 352 128.855 l 356.43 128.855 360 132.422 360 136.855 c
360 184.855 l 360 189.285 356.43 192.855 352 192.855 c 17.555 192.855 l
13.121 192.855 9.555 189.285 9.555 184.855 c 9.555 136.855 l 9.555
132.422 13.121 128.855 17.555 128.855 c h
17.555 128.855 m S Q
0.34902 0.454902 0.709804 rg
230.398 49.604 m 308.84 49.604 l 313.273 49.604 316.84 46.038 316.84
41.604 c 316.84 25.604 l 316.84 21.174 313.273 17.604 308.84 17.604 c
230.398 17.604 l 225.965 17.604 222.398 21.174 222.398 25.604 c 222.398
41.604 l 222.398 46.038 225.965 49.604 230.398 49.604 c h
230.398 49.604 m f*
0.215686 0.294118 0.490196 rg
q 1 0 0 -1 0 202.459579 cm
230.398 152.855 m 308.84 152.855 l 313.273 152.855 316.84 156.422
316.84 160.855 c 316.84 176.855 l 316.84 181.285 313.273 184.855 308.84
184.855 c 230.398 184.855 l 225.965 184.855 222.398 181.285 222.398
176.855 c 222.398 160.855 l 222.398 156.422 225.965 152.855 230.398
152.855 c h
230.398 152.855 m S Q
0 g
BT
11.2 0 0 11.2 235.879565 29.63477 Tm
/f-1-0 1 Tf
[<01>-1<020304>-1<01>-1<05>7<06>-1<07>19<0308>1<09>-1<02>19<07>19<0a>]TJ
ET
0.16 w
q 1 0 0 -1 0 202.459579 cm
237.582 164.652 m 236.645 164.652 l 236.645 172.824 l 237.582 172.824 l
h
241.422 166.793 m 239.781 166.793 238.781 167.965 238.781 169.934 c
238.781 171.902 239.766 173.074 241.438 173.074 c 243.078 173.074
244.094 171.902 244.094 169.98 c 244.094 167.949 243.109 166.793
241.422 166.793 c h
241.438 167.652 m 242.484 167.652 243.109 168.512 243.109 169.965 c
243.109 171.34 242.469 172.215 241.438 172.215 c 240.391 172.215 239.75
171.355 239.75 169.934 c 239.75 168.527 240.391 167.652 241.438 167.652
c h
249.891 168.918 m 249.781 167.527 248.906 166.793 247.562 166.793 c
245.984 166.793 244.953 168.043 244.953 169.996 c 244.953 171.887
245.969 173.074 247.562 173.074 c 248.953 173.074 249.844 172.246
249.953 170.809 c 249.016 170.809 l 248.859 171.746 248.375 172.215
247.578 172.215 c 246.547 172.215 245.938 171.387 245.938 169.996 c
245.938 168.527 246.531 167.652 247.562 167.652 c 248.344 167.652
248.828 168.105 248.938 168.918 c h
250.941 168.684 m 251.879 168.684 l 251.957 167.98 252.379 167.652
253.254 167.652 c 254.098 167.652 254.566 167.965 254.566 168.527 c
254.566 168.762 l 254.566 169.168 254.332 169.324 253.598 169.418 c
251.879 169.637 250.676 169.777 250.676 171.34 c 250.676 172.402 251.41
173.074 252.598 173.074 c 253.348 173.074 253.941 172.824 254.598
172.215 c 254.66 172.809 254.957 173.074 255.566 173.074 c 255.754
173.074 255.895 173.059 256.207 172.98 c 256.207 172.277 l 256.098
172.293 256.051 172.293 256.004 172.293 c 255.676 172.293 255.488
172.137 255.488 171.84 c 255.488 168.387 l 255.488 167.34 254.738
166.793 253.285 166.793 c 252.238 166.793 250.988 167.105 250.941
168.684 c h
252.801 172.262 m 252.082 172.262 251.645 171.918 251.645 171.324 c
251.645 170.027 253.613 170.355 254.566 169.918 c 254.566 170.98 l
254.566 171.543 253.91 172.262 252.801 172.262 c h
258.145 164.652 m 257.207 164.652 l 257.207 172.824 l 258.145 172.824 l
h
261.828 166.949 m 260.859 166.949 l 260.859 166.043 l 260.859 165.637
261.078 165.449 261.5 165.449 c 261.578 165.449 261.609 165.449 261.828
165.449 c 261.828 164.684 l 261.609 164.637 261.484 164.621 261.297
164.621 c 260.438 164.621 259.922 165.121 259.922 165.949 c 259.922
166.949 l 259.141 166.949 l 259.141 167.715 l 259.922 167.715 l 259.922
172.824 l 260.859 172.824 l 260.859 167.715 l 261.828 167.715 l h
267.383 172.824 m 267.383 166.949 l 266.445 166.949 l 266.445 170.277 l
266.445 171.48 265.82 172.262 264.852 172.262 c 264.102 172.262 263.633
171.809 263.633 171.105 c 263.633 166.949 l 262.711 166.949 l 262.711
171.48 l 262.711 172.449 263.43 173.074 264.57 173.074 c 265.445
173.074 265.992 172.777 266.539 172.012 c 266.539 172.824 l h
268.992 166.949 m 268.992 172.824 l 269.93 172.824 l 269.93 169.59 l
269.93 168.387 270.57 167.605 271.523 167.605 c 272.273 167.605 272.742
168.059 272.742 168.762 c 272.742 172.824 l 273.664 172.824 l 273.664
168.387 l 273.664 167.418 272.945 166.793 271.805 166.793 c 270.93
166.793 270.367 167.121 269.852 167.934 c 269.852 166.949 l h
279.508 168.918 m 279.398 167.527 278.523 166.793 277.18 166.793 c
275.602 166.793 274.57 168.043 274.57 169.996 c 274.57 171.887 275.586
173.074 277.18 173.074 c 278.57 173.074 279.461 172.246 279.57 170.809
c 278.633 170.809 l 278.477 171.746 277.992 172.215 277.195 172.215 c
276.164 172.215 275.555 171.387 275.555 169.996 c 275.555 168.527
276.148 167.652 277.18 167.652 c 277.961 167.652 278.445 168.105
278.555 168.918 c h
282.672 166.949 m 281.703 166.949 l 281.703 165.34 l 280.781 165.34 l
280.781 166.949 l 279.984 166.949 l 279.984 167.715 l 280.781 167.715 l
280.781 172.152 l 280.781 172.746 281.188 173.074 281.906 173.074 c
282.141 173.074 282.359 173.059 282.672 172.996 c 282.672 172.215 l
282.547 172.246 282.406 172.262 282.219 172.262 c 281.828 172.262
281.703 172.152 281.703 171.73 c 281.703 167.715 l 282.672 167.715 l h
284.621 166.949 m 283.684 166.949 l 283.684 172.824 l 284.621 172.824 l
h
284.621 164.652 m 283.668 164.652 l 283.668 165.84 l 284.621 165.84 l h
288.473 166.793 m 286.832 166.793 285.832 167.965 285.832 169.934 c
285.832 171.902 286.816 173.074 288.488 173.074 c 290.129 173.074
291.145 171.902 291.145 169.98 c 291.145 167.949 290.16 166.793 288.473
166.793 c h
288.488 167.652 m 289.535 167.652 290.16 168.512 290.16 169.965 c
290.16 171.34 289.52 172.215 288.488 172.215 c 287.441 172.215 286.801
171.355 286.801 169.934 c 286.801 168.527 287.441 167.652 288.488
167.652 c h
292.223 166.949 m 292.223 172.824 l 293.16 172.824 l 293.16 169.59 l
293.16 168.387 293.801 167.605 294.754 167.605 c 295.504 167.605
295.973 168.059 295.973 168.762 c 295.973 172.824 l 296.895 172.824 l
296.895 168.387 l 296.895 167.418 296.176 166.793 295.035 166.793 c
294.16 166.793 293.598 167.121 293.082 167.934 c 293.082 166.949 l h
298.816 171.074 m 297.832 171.074 l 297.879 172.434 298.645 173.074
300.176 173.074 c 301.66 173.074 302.598 172.355 302.598 171.215 c
302.598 170.355 302.113 169.871 300.941 169.59 c 300.051 169.371 l
299.285 169.199 298.957 168.949 298.957 168.527 c 298.957 167.996
299.441 167.652 300.207 167.652 c 300.957 167.652 301.363 167.98
301.379 168.59 c 302.363 168.59 l 302.348 167.434 301.598 166.793
300.238 166.793 c 298.863 166.793 297.988 167.496 297.988 168.574 c
297.988 169.496 298.457 169.934 299.848 170.277 c 300.723 170.48 l
301.363 170.637 301.629 170.871 301.629 171.293 c 301.629 171.855
301.082 172.215 300.254 172.215 c 299.113 172.215 298.895 171.652
298.816 171.074 c h
298.816 171.074 m S Q
0.34902 0.454902 0.709804 rg
128 49.604 m 206.441 49.604 l 210.875 49.604 214.441 46.038 214.441
41.604 c 214.441 25.604 l 214.441 21.174 210.875 17.604 206.441 17.604
c 128 17.604 l 123.566 17.604 120 21.174 120 25.604 c 120 41.604 l 120
46.038 123.566 49.604 128 49.604 c h
128 49.604 m f*
0.215686 0.294118 0.490196 rg
3.2 w
q 1 0 0 -1 0 202.459579 cm
128 152.855 m 206.441 152.855 l 210.875 152.855 214.441 156.422 214.441
160.855 c 214.441 176.855 l 214.441 181.285 210.875 184.855 206.441
184.855 c 128 184.855 l 123.566 184.855 120 181.285 120 176.855 c 120
160.855 l 120 156.422 123.566 152.855 128 152.855 c h
128 152.855 m S Q
0 g
BT
11.2 0 0 11.2 160.508398 29.651567 Tm
/f-1-0 1 Tf
[<09>-1<0a>20<0801>]TJ
ET
0.16 w
q 1 0 0 -1 0 202.459579 cm
162.195 166.934 m 161.258 166.934 l 161.258 172.809 l 162.195 172.809 l
h
162.195 164.637 m 161.242 164.637 l 161.242 165.824 l 162.195 165.824 l
h
164.363 171.059 m 163.379 171.059 l 163.426 172.418 164.191 173.059
165.723 173.059 c 167.207 173.059 168.145 172.34 168.145 171.199 c
168.145 170.34 167.66 169.855 166.488 169.574 c 165.598 169.355 l
164.832 169.184 164.504 168.934 164.504 168.512 c 164.504 167.98
164.988 167.637 165.754 167.637 c 166.504 167.637 166.91 167.965
166.926 168.574 c 167.91 168.574 l 167.895 167.418 167.145 166.777
165.785 166.777 c 164.41 166.777 163.535 167.48 163.535 168.559 c
163.535 169.48 164.004 169.918 165.395 170.262 c 166.27 170.465 l
166.91 170.621 167.176 170.855 167.176 171.277 c 167.176 171.84 166.629
172.199 165.801 172.199 c 164.66 172.199 164.441 171.637 164.363
171.059 c h
171.227 166.934 m 170.258 166.934 l 170.258 165.324 l 169.336 165.324 l
169.336 166.934 l 168.539 166.934 l 168.539 167.699 l 169.336 167.699 l
169.336 172.137 l 169.336 172.73 169.742 173.059 170.461 173.059 c
170.695 173.059 170.914 173.043 171.227 172.98 c 171.227 172.199 l
171.102 172.23 170.961 172.246 170.773 172.246 c 170.383 172.246
170.258 172.137 170.258 171.715 c 170.258 167.699 l 171.227 167.699 l h
173.191 164.637 m 172.254 164.637 l 172.254 172.809 l 173.191 172.809 l
h
173.191 164.637 m S Q
0.34902 0.454902 0.709804 rg
25.555 49.604 m 104 49.604 l 108.43 49.604 112 46.038 112 41.604 c 112
25.604 l 112 21.174 108.43 17.604 104 17.604 c 25.555 17.604 l 21.121
17.604 17.555 21.174 17.555 25.604 c 17.555 41.604 l 17.555 46.038
21.121 49.604 25.555 49.604 c h
25.555 49.604 m f*
0.215686 0.294118 0.490196 rg
3.2 w
q 1 0 0 -1 0 202.459579 cm
25.555 152.855 m 104 152.855 l 108.43 152.855 112 156.422 112 160.855 c
112 176.855 l 112 181.285 108.43 184.855 104 184.855 c 25.555 184.855 l
21.121 184.855 17.555 181.285 17.555 176.855 c 17.555 160.855 l 17.555
156.422 21.121 152.855 25.555 152.855 c h
25.555 152.855 m S Q
0 g
BT
11.2 0 0 11.2 55.607773 30.743583 Tm
/f-1-0 1 Tf
[<0b>-1<0c>-1<090d>]TJ
ET
0.16 w
q 1 0 0 -1 0 202.459579 cm
58.359 171.965 m 59.094 171.965 59.609 171.652 60.141 170.918 c 60.141
171.215 l 60.141 172.559 59.828 173.371 58.5 173.371 c 58.203 173.371
57.234 173.34 57.078 172.387 c 56.125 172.387 l 56.219 173.496 57.094
174.152 58.469 174.152 c 60.703 174.152 61.094 172.793 61.094 170.746 c
61.094 165.84 l 60.219 165.84 l 60.219 166.699 l 59.75 165.996 59.188
165.684 58.438 165.684 c 56.938 165.684 55.938 166.98 55.938 168.887 c
55.938 170.793 57.016 171.965 58.359 171.965 c h
58.531 166.543 m 59.547 166.543 60.141 167.387 60.141 168.855 c 60.141
170.262 59.531 171.105 58.547 171.105 c 57.531 171.105 56.906 170.246
56.906 168.824 c 56.906 167.418 57.531 166.543 58.531 166.543 c h
65.438 166.668 m 65.438 165.715 l 65.281 165.684 65.203 165.684 65.078
165.684 c 64.469 165.684 64.016 166.027 63.484 166.902 c 63.484 165.84
l 62.609 165.84 l 62.609 171.715 l 63.562 171.715 l 63.562 168.668 l
63.562 167.027 64.312 166.684 65.438 166.668 c h
67.27 165.84 m 66.332 165.84 l 66.332 171.715 l 67.27 171.715 l h
67.27 163.543 m 66.316 163.543 l 66.316 164.73 l 67.27 164.73 l h
73.625 163.543 m 72.688 163.543 l 72.688 166.59 l 72.297 165.996 71.672
165.684 70.891 165.684 c 69.359 165.684 68.375 166.902 68.375 168.762 c
68.375 170.746 69.344 171.965 70.922 171.965 c 71.734 171.965 72.297
171.668 72.797 170.949 c 72.797 171.715 l 73.625 171.715 l h
71.047 166.543 m 72.062 166.543 72.688 167.449 72.688 168.84 c 72.688
170.199 72.047 171.105 71.062 171.105 c 70.031 171.105 69.344 170.184
69.344 168.824 c 69.344 167.465 70.031 166.543 71.047 166.543 c h
71.047 166.543 m S Q
0.196078 g
BT
11.2 0 0 11.2 17.554914 57.605192 Tm
/f-0-0 1 Tf
[<05>5<07>15<0c>1<0a>-1<0d>1<10>6<07>5<0f>10<11>19<03>10<0a>9<09>]TJ
ET
0.905882 0.952941 1 rg
17.598 145.604 m 153.598 145.604 l 158.031 145.604 161.598 142.038
161.598 137.604 c 161.598 89.604 l 161.598 85.174 158.031 81.604
153.598 81.604 c 17.598 81.604 l 13.168 81.604 9.598 85.174 9.598
89.604 c 9.598 137.604 l 9.598 142.038 13.168 145.604 17.598 145.604 c
h
17.598 145.604 m f*
0.690196 0.737255 0.894118 rg
3.2 w
q 1 0 0 -1 0 202.459579 cm
17.598 56.855 m 153.598 56.855 l 158.031 56.855 161.598 60.422 161.598
64.855 c 161.598 112.855 l 161.598 117.285 158.031 120.855 153.598
120.855 c 17.598 120.855 l 13.168 120.855 9.598 117.285 9.598 112.855 c
9.598 64.855 l 9.598 60.422 13.168 56.855 17.598 56.855 c h
17.598 56.855 m S Q
0.784314 0.835294 1 rg
25.598 121.604 m 57.598 121.604 l 62.031 121.604 65.598 118.038 65.598
113.604 c 65.598 97.604 l 65.598 93.174 62.031 89.604 57.598 89.604 c
25.598 89.604 l 21.168 89.604 17.598 93.174 17.598 97.604 c 17.598
113.604 l 17.598 118.038 21.168 121.604 25.598 121.604 c h
25.598 121.604 m f*
0.34902 0.454902 0.709804 rg
q 1 0 0 -1 0 202.459579 cm
25.598 80.855 m 57.598 80.855 l 62.031 80.855 65.598 84.422 65.598
88.855 c 65.598 104.855 l 65.598 109.285 62.031 112.855 57.598 112.855
c 25.598 112.855 l 21.168 112.855 17.598 109.285 17.598 104.855 c
17.598 88.855 l 17.598 84.422 21.168 80.855 25.598 80.855 c h
25.598 80.855 m S Q
0 g
BT
11.2 0 0 11.2 24.617719 102.515336 Tm
/f-1-0 1 Tf
[<0e>-1<0d>9<0f01>-1<04>-1<10>]TJ
ET
0.16 w
q 1 0 0 -1 0 202.459579 cm
25.227 102.383 m 26.164 102.383 l 26.164 99.336 l 26.648 99.93 27.211
100.195 27.961 100.195 c 29.477 100.195 30.477 98.977 30.477 97.117 c
30.477 95.133 29.508 93.914 27.961 93.914 c 27.164 93.914 26.523 94.258
26.086 94.961 c 26.086 94.07 l 25.227 94.07 l h
27.805 94.773 m 28.836 94.773 29.508 95.695 29.508 97.086 c 29.508
98.414 28.82 99.336 27.805 99.336 c 26.82 99.336 26.164 98.43 26.164
97.055 c 26.164 95.68 26.82 94.773 27.805 94.773 c h
36.398 91.773 m 35.461 91.773 l 35.461 94.82 l 35.07 94.227 34.445
93.914 33.664 93.914 c 32.133 93.914 31.148 95.133 31.148 96.992 c
31.148 98.977 32.117 100.195 33.695 100.195 c 34.508 100.195 35.07
99.898 35.57 99.18 c 35.57 99.945 l 36.398 99.945 l h
33.82 94.773 m 34.836 94.773 35.461 95.68 35.461 97.07 c 35.461 98.43
34.82 99.336 33.836 99.336 c 32.805 99.336 32.117 98.414 32.117 97.055
c 32.117 95.695 32.805 94.773 33.82 94.773 c h
42.727 97.32 m 42.727 96.43 42.664 95.883 42.492 95.445 c 42.102 94.492
41.211 93.914 40.117 93.914 c 38.477 93.914 37.43 95.164 37.43 97.086 c
37.43 99.008 38.445 100.195 40.086 100.195 c 41.43 100.195 42.367
99.445 42.602 98.164 c 41.664 98.164 l 41.398 98.93 40.883 99.336
40.117 99.336 c 39.523 99.336 39.023 99.07 38.711 98.586 c 38.492
98.242 38.414 97.914 38.398 97.32 c h
38.414 96.555 m 38.508 95.477 39.164 94.773 40.102 94.773 c 41.023
94.773 41.727 95.539 41.727 96.492 c 41.727 96.523 41.727 96.539 41.711
96.555 c h
44.914 91.773 m 43.977 91.773 l 43.977 99.945 l 44.914 99.945 l h
46.441 95.805 m 47.379 95.805 l 47.457 95.102 47.879 94.773 48.754
94.773 c 49.598 94.773 50.066 95.086 50.066 95.648 c 50.066 95.883 l
50.066 96.289 49.832 96.445 49.098 96.539 c 47.379 96.758 46.176 96.898
46.176 98.461 c 46.176 99.523 46.91 100.195 48.098 100.195 c 48.848
100.195 49.441 99.945 50.098 99.336 c 50.16 99.93 50.457 100.195 51.066
100.195 c 51.254 100.195 51.395 100.18 51.707 100.102 c 51.707 99.398 l
51.598 99.414 51.551 99.414 51.504 99.414 c 51.176 99.414 50.988 99.258
50.988 98.961 c 50.988 95.508 l 50.988 94.461 50.238 93.914 48.785
93.914 c 47.738 93.914 46.488 94.227 46.441 95.805 c h
48.301 99.383 m 47.582 99.383 47.145 99.039 47.145 98.445 c 47.145
97.148 49.113 97.477 50.066 97.039 c 50.066 98.102 l 50.066 98.664
49.41 99.383 48.301 99.383 c h
52.551 91.773 m 52.551 99.945 l 53.379 99.945 l 53.379 99.195 l 53.832
99.883 54.426 100.195 55.254 100.195 c 56.785 100.195 57.801 98.93
57.801 96.992 c 57.801 95.086 56.832 93.914 55.285 93.914 c 54.488
93.914 53.91 94.211 53.473 94.867 c 53.473 91.773 l h
55.113 94.773 m 56.16 94.773 56.832 95.695 56.832 97.086 c 56.832
98.414 56.129 99.336 55.113 99.336 c 54.129 99.336 53.473 98.43 53.473
97.055 c 53.473 95.68 54.129 94.773 55.113 94.773 c h
55.113 94.773 m S Q
0.784314 0.835294 1 rg
80 121.604 m 112 121.604 l 116.43 121.604 120 118.038 120 113.604 c 120
97.604 l 120 93.174 116.43 89.604 112 89.604 c 80 89.604 l 75.566
89.604 72 93.174 72 97.604 c 72 113.604 l 72 118.038 75.566 121.604 80
121.604 c h
80 121.604 m f*
0.34902 0.454902 0.709804 rg
3.2 w
q 1 0 0 -1 0 202.459579 cm
80 80.855 m 112 80.855 l 116.43 80.855 120 84.422 120 88.855 c 120
104.855 l 120 109.285 116.43 112.855 112 112.855 c 80 112.855 l 75.566
112.855 72 109.285 72 104.855 c 72 88.855 l 72 84.422 75.566 80.855 80
80.855 c h
80 80.855 m S Q
0 g
BT
11.2 0 0 11.2 87.259125 101.429777 Tm
/f-1-0 1 Tf
[<05>26<0f>19<11>]TJ
ET
0.16 w
q 1 0 0 -1 0 202.459579 cm
90.148 95.156 m 89.18 95.156 l 89.18 94.25 l 89.18 93.844 89.398 93.656
89.82 93.656 c 89.898 93.656 89.93 93.656 90.148 93.656 c 90.148 92.891
l 89.93 92.844 89.805 92.828 89.617 92.828 c 88.758 92.828 88.242
93.328 88.242 94.156 c 88.242 95.156 l 87.461 95.156 l 87.461 95.922 l
88.242 95.922 l 88.242 101.031 l 89.18 101.031 l 89.18 95.922 l 90.148
95.922 l h
95.832 98.406 m 95.832 97.516 95.77 96.969 95.598 96.531 c 95.207
95.578 94.316 95 93.223 95 c 91.582 95 90.535 96.25 90.535 98.172 c
90.535 100.094 91.551 101.281 93.191 101.281 c 94.535 101.281 95.473
100.531 95.707 99.25 c 94.77 99.25 l 94.504 100.016 93.988 100.422
93.223 100.422 c 92.629 100.422 92.129 100.156 91.816 99.672 c 91.598
99.328 91.52 99 91.504 98.406 c h
91.52 97.641 m 91.613 96.562 92.27 95.859 93.207 95.859 c 94.129 95.859
94.832 96.625 94.832 97.578 c 94.832 97.609 94.832 97.625 94.816 97.641
c h
96.879 95.156 m 96.879 101.031 l 97.816 101.031 l 97.816 97.344 l
97.816 96.5 98.441 95.812 99.207 95.812 c 99.895 95.812 100.285 96.234
100.285 96.984 c 100.285 101.031 l 101.223 101.031 l 101.223 97.344 l
101.223 96.5 101.848 95.812 102.613 95.812 c 103.285 95.812 103.691
96.25 103.691 96.984 c 103.691 101.031 l 104.629 101.031 l 104.629
96.625 l 104.629 95.578 104.035 95 102.926 95 c 102.145 95 101.676
95.234 101.129 95.891 c 100.785 95.266 100.316 95 99.551 95 c 98.77 95
98.254 95.281 97.738 95.984 c 97.738 95.156 l h
96.879 95.156 m S Q
0.196078 g
BT
11.2 0 0 11.2 17.598188 129.60518 Tm
/f-0-0 1 Tf
[<0f>19<04>11<09>9<05>9<0c0a>5<06>15<0412>20<01>19<06>14<04>21<07>29<08>-1<0d>1<10>6<07>5<0f>10<11>19<03>10<0a>9<09>]TJ
ET
0.905882 0.952941 1 rg
260 145.604 m 352 145.604 l 356.43 145.604 360 142.038 360 137.604 c
360 89.604 l 360 85.174 356.43 81.604 352 81.604 c 260 81.604 l 255.566
81.604 252 85.174 252 89.604 c 252 137.604 l 252 142.038 255.566
145.604 260 145.604 c h
260 145.604 m f*
0.690196 0.737255 0.894118 rg
3.2 w
q 1 0 0 -1 0 202.459579 cm
260 56.855 m 352 56.855 l 356.43 56.855 360 60.422 360 64.855 c 360
112.855 l 360 117.285 356.43 120.855 352 120.855 c 260 120.855 l
255.566 120.855 252 117.285 252 112.855 c 252 64.855 l 252 60.422
255.566 56.855 260 56.855 c h
260 56.855 m S Q
0.196078 g
BT
11.2 0 0 11.2 259.998218 129.60518 Tm
/f-0-0 1 Tf
[<0a>25<0b>9<06>5<0a>5<0c>6<08>9<01>15<03>1<0d>1<10>6<07>5<0f>10<11>19<03>10<0a>9<09>]TJ
ET
0.34902 0.454902 0.709804 rg
340.969 33.604 m 340.969 32.026 339.691 30.749 338.113 30.749 c 336.535
30.749 335.254 32.026 335.254 33.604 c 335.254 35.182 336.535 36.463
338.113 36.463 c 339.691 36.463 340.969 35.182 340.969 33.604 c h
340.969 33.604 m f
0.215686 0.294118 0.490196 rg
q 1 0 0 -1 0 202.459579 cm
340.969 168.855 m 340.969 170.434 339.691 171.711 338.113 171.711 c
336.535 171.711 335.254 170.434 335.254 168.855 c 335.254 167.277
336.535 165.996 338.113 165.996 c 339.691 165.996 340.969 167.277
340.969 168.855 c h
340.969 168.855 m S Q
0.34902 0.454902 0.709804 rg
351.543 33.604 m 351.543 32.026 350.262 30.749 348.684 30.749 c 347.105
30.749 345.828 32.026 345.828 33.604 c 345.828 35.182 347.105 36.463
348.684 36.463 c 350.262 36.463 351.543 35.182 351.543 33.604 c h
351.543 33.604 m f
0.215686 0.294118 0.490196 rg
q 1 0 0 -1 0 202.459579 cm
351.543 168.855 m 351.543 170.434 350.262 171.711 348.684 171.711 c
347.105 171.711 345.828 170.434 345.828 168.855 c 345.828 167.277
347.105 165.996 348.684 165.996 c 350.262 165.996 351.543 167.277
351.543 168.855 c h
351.543 168.855 m S Q
0.34902 0.454902 0.709804 rg
330.398 33.604 m 330.398 32.026 329.117 30.749 327.543 30.749 c 325.965
30.749 324.684 32.026 324.684 33.604 c 324.684 35.182 325.965 36.463
327.543 36.463 c 329.117 36.463 330.398 35.182 330.398 33.604 c h
330.398 33.604 m f
0.215686 0.294118 0.490196 rg
q 1 0 0 -1 0 202.459579 cm
330.398 168.855 m 330.398 170.434 329.117 171.711 327.543 171.711 c
325.965 171.711 324.684 170.434 324.684 168.855 c 324.684 167.277
325.965 165.996 327.543 165.996 c 329.117 165.996 330.398 167.277
330.398 168.855 c h
330.398 168.855 m S Q
0.784314 0.835294 1 rg
143.371 105.604 m 143.371 104.026 142.09 102.749 140.512 102.749 c
138.934 102.749 137.656 104.026 137.656 105.604 c 137.656 107.182
138.934 108.463 140.512 108.463 c 142.09 108.463 143.371 107.182
143.371 105.604 c h
143.371 105.604 m f
0.34902 0.454902 0.709804 rg
q 1 0 0 -1 0 202.459579 cm
143.371 96.855 m 143.371 98.434 142.09 99.711 140.512 99.711 c 138.934
99.711 137.656 98.434 137.656 96.855 c 137.656 95.277 138.934 93.996
140.512 93.996 c 142.09 93.996 143.371 95.277 143.371 96.855 c h
143.371 96.855 m S Q
0.784314 0.835294 1 rg
153.941 105.604 m 153.941 104.026 152.66 102.749 151.082 102.749 c
149.508 102.749 148.227 104.026 148.227 105.604 c 148.227 107.182
149.508 108.463 151.082 108.463 c 152.66 108.463 153.941 107.182
153.941 105.604 c h
153.941 105.604 m f
0.34902 0.454902 0.709804 rg
q 1 0 0 -1 0 202.459579 cm
153.941 96.855 m 153.941 98.434 152.66 99.711 151.082 99.711 c 149.508
99.711 148.227 98.434 148.227 96.855 c 148.227 95.277 149.508 93.996
151.082 93.996 c 152.66 93.996 153.941 95.277 153.941 96.855 c h
153.941 96.855 m S Q
0.784314 0.835294 1 rg
132.797 105.604 m 132.797 104.026 131.52 102.749 129.941 102.749 c
128.363 102.749 127.082 104.026 127.082 105.604 c 127.082 107.182
128.363 108.463 129.941 108.463 c 131.52 108.463 132.797 107.182
132.797 105.604 c h
132.797 105.604 m f
0.34902 0.454902 0.709804 rg
q 1 0 0 -1 0 202.459579 cm
132.797 96.855 m 132.797 98.434 131.52 99.711 129.941 99.711 c 128.363
99.711 127.082 98.434 127.082 96.855 c 127.082 95.277 128.363 93.996
129.941 93.996 c 131.52 93.996 132.797 95.277 132.797 96.855 c h
132.797 96.855 m S Q
0.784314 0.835294 1 rg
209.254 105.604 m 209.254 104.026 207.977 102.749 206.398 102.749 c
204.82 102.749 203.543 104.026 203.543 105.604 c 203.543 107.182 204.82
108.463 206.398 108.463 c 207.977 108.463 209.254 107.182 209.254
105.604 c h
209.254 105.604 m f
0.34902 0.454902 0.709804 rg
q 1 0 0 -1 0 202.459579 cm
209.254 96.855 m 209.254 98.434 207.977 99.711 206.398 99.711 c 204.82
99.711 203.543 98.434 203.543 96.855 c 203.543 95.277 204.82 93.996
206.398 93.996 c 207.977 93.996 209.254 95.277 209.254 96.855 c h
209.254 96.855 m S Q
0.784314 0.835294 1 rg
219.828 105.604 m 219.828 104.026 218.547 102.749 216.969 102.749 c
215.391 102.749 214.113 104.026 214.113 105.604 c 214.113 107.182
215.391 108.463 216.969 108.463 c 218.547 108.463 219.828 107.182
219.828 105.604 c h
219.828 105.604 m f
0.34902 0.454902 0.709804 rg
q 1 0 0 -1 0 202.459579 cm
219.828 96.855 m 219.828 98.434 218.547 99.711 216.969 99.711 c 215.391
99.711 214.113 98.434 214.113 96.855 c 214.113 95.277 215.391 93.996
216.969 93.996 c 218.547 93.996 219.828 95.277 219.828 96.855 c h
219.828 96.855 m S Q
0.784314 0.835294 1 rg
198.684 105.604 m 198.684 104.026 197.406 102.749 195.828 102.749 c
194.25 102.749 192.969 104.026 192.969 105.604 c 192.969 107.182 194.25
108.463 195.828 108.463 c 197.406 108.463 198.684 107.182 198.684
105.604 c h
198.684 105.604 m f
0.34902 0.454902 0.709804 rg
q 1 0 0 -1 0 202.459579 cm
198.684 96.855 m 198.684 98.434 197.406 99.711 195.828 99.711 c 194.25
99.711 192.969 98.434 192.969 96.855 c 192.969 95.277 194.25 93.996
195.828 93.996 c 197.406 93.996 198.684 95.277 198.684 96.855 c h
198.684 96.855 m S Q
0.784314 0.835294 1 rg
308.855 105.604 m 308.855 104.026 307.574 102.749 306 102.749 c 304.422
102.749 303.141 104.026 303.141 105.604 c 303.141 107.182 304.422
108.463 306 108.463 c 307.574 108.463 308.855 107.182 308.855 105.604 c
h
308.855 105.604 m f
0.34902 0.454902 0.709804 rg
q 1 0 0 -1 0 202.459579 cm
308.855 96.855 m 308.855 98.434 307.574 99.711 306 99.711 c 304.422
99.711 303.141 98.434 303.141 96.855 c 303.141 95.277 304.422 93.996
306 93.996 c 307.574 93.996 308.855 95.277 308.855 96.855 c h
308.855 96.855 m S Q
0.784314 0.835294 1 rg
319.426 105.604 m 319.426 104.026 318.148 102.749 316.57 102.749 c
314.992 102.749 313.711 104.026 313.711 105.604 c 313.711 107.182
314.992 108.463 316.57 108.463 c 318.148 108.463 319.426 107.182
319.426 105.604 c h
319.426 105.604 m f
0.34902 0.454902 0.709804 rg
q 1 0 0 -1 0 202.459579 cm
319.426 96.855 m 319.426 98.434 318.148 99.711 316.57 99.711 c 314.992
99.711 313.711 98.434 313.711 96.855 c 313.711 95.277 314.992 93.996
316.57 93.996 c 318.148 93.996 319.426 95.277 319.426 96.855 c h
319.426 96.855 m S Q
0.784314 0.835294 1 rg
298.285 105.604 m 298.285 104.026 297.004 102.749 295.426 102.749 c
293.848 102.749 292.57 104.026 292.57 105.604 c 292.57 107.182 293.848
108.463 295.426 108.463 c 297.004 108.463 298.285 107.182 298.285
105.604 c h
298.285 105.604 m f
0.34902 0.454902 0.709804 rg
q 1 0 0 -1 0 202.459579 cm
298.285 96.855 m 298.285 98.434 297.004 99.711 295.426 99.711 c 293.848
99.711 292.57 98.434 292.57 96.855 c 292.57 95.277 293.848 93.996
295.426 93.996 c 297.004 93.996 298.285 95.277 298.285 96.855 c h
298.285 96.855 m S Q
Q Q
showpage
%%Trailer
count op_count sub {pop} repeat
countdictstack dict_count sub {end} repeat
cairo_eps_state restore
%%EOF

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,154 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Title: exercise1_c.fig
%%Creator: fig2dev Version 3.2 Patchlevel 5
%%CreationDate: Mon Nov 10 16:50:24 2008
%%For: melanie@alvine (Melanie Darcis)
%%BoundingBox: 0 0 283 107
%Magnification: 1.0000
%%EndComments
/$F2psDict 200 dict def
$F2psDict begin
$F2psDict /mtrx matrix put
/col-1 {0 setgray} bind def
/col0 {0.000 0.000 0.000 srgb} bind def
/col1 {0.000 0.000 1.000 srgb} bind def
/col2 {0.000 1.000 0.000 srgb} bind def
/col3 {0.000 1.000 1.000 srgb} bind def
/col4 {1.000 0.000 0.000 srgb} bind def
/col5 {1.000 0.000 1.000 srgb} bind def
/col6 {1.000 1.000 0.000 srgb} bind def
/col7 {1.000 1.000 1.000 srgb} bind def
/col8 {0.000 0.000 0.560 srgb} bind def
/col9 {0.000 0.000 0.690 srgb} bind def
/col10 {0.000 0.000 0.820 srgb} bind def
/col11 {0.530 0.810 1.000 srgb} bind def
/col12 {0.000 0.560 0.000 srgb} bind def
/col13 {0.000 0.690 0.000 srgb} bind def
/col14 {0.000 0.820 0.000 srgb} bind def
/col15 {0.000 0.560 0.560 srgb} bind def
/col16 {0.000 0.690 0.690 srgb} bind def
/col17 {0.000 0.820 0.820 srgb} bind def
/col18 {0.560 0.000 0.000 srgb} bind def
/col19 {0.690 0.000 0.000 srgb} bind def
/col20 {0.820 0.000 0.000 srgb} bind def
/col21 {0.560 0.000 0.560 srgb} bind def
/col22 {0.690 0.000 0.690 srgb} bind def
/col23 {0.820 0.000 0.820 srgb} bind def
/col24 {0.500 0.190 0.000 srgb} bind def
/col25 {0.630 0.250 0.000 srgb} bind def
/col26 {0.750 0.380 0.000 srgb} bind def
/col27 {1.000 0.500 0.500 srgb} bind def
/col28 {1.000 0.630 0.630 srgb} bind def
/col29 {1.000 0.750 0.750 srgb} bind def
/col30 {1.000 0.880 0.880 srgb} bind def
/col31 {1.000 0.840 0.000 srgb} bind def
end
save
newpath 0 107 moveto 0 0 lineto 283 0 lineto 283 107 lineto closepath clip newpath
-169.1 349.4 translate
1 -1 scale
/cp {closepath} bind def
/ef {eofill} bind def
/gr {grestore} bind def
/gs {gsave} bind def
/sa {save} bind def
/rs {restore} bind def
/l {lineto} bind def
/m {moveto} bind def
/rm {rmoveto} bind def
/n {newpath} bind def
/s {stroke} bind def
/sh {show} bind def
/slc {setlinecap} bind def
/slj {setlinejoin} bind def
/slw {setlinewidth} bind def
/srgb {setrgbcolor} bind def
/rot {rotate} bind def
/sc {scale} bind def
/sd {setdash} bind def
/ff {findfont} bind def
/sf {setfont} bind def
/scf {scalefont} bind def
/sw {stringwidth} bind def
/tr {translate} bind def
/tnt {dup dup currentrgbcolor
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
bind def
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
4 -2 roll mul srgb} bind def
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
/$F2psEnd {$F2psEnteredState restore end} def
$F2psBegin
10 setmiterlimit
0 slj 0 slc
0.06299 0.06299 sc
%
% Fig objects follow
%
%
% here starts figure with depth 50
% Polyline
0 slj
0 slc
7.500 slw
n 3285 5310 m
3285 5535 l gs col0 s gr
% Polyline
n 3285 5445 m
4905 5445 l gs col0 s gr
% Polyline
n 5715 5445 m
7155 5445 l gs col0 s gr
% Polyline
n 7155 5310 m
7155 5535 l gs col0 s gr
% Polyline
n 3060 4725 m
3060 5040 l gs col0 s gr
% Polyline
n 2970 5130 m
3150 5130 l gs col0 s gr
% Polyline
n 3060 4680 m
3060 5130 l gs col0 s gr
% Polyline
n 3240 3870 m 7155 3870 l 7155 5130 l 3240 5130 l
cp gs col0 s gr
% Polyline
n 5265 3870 m 7155 3870 l 7155 5130 l 5265 5130 l
cp gs col15 1.00 shd ef gr gs col0 s gr
% Polyline
n 3060 3870 m
3060 4320 l gs col0 s gr
% Polyline
n 2970 3870 m
3150 3870 l gs col0 s gr
/Times-Roman ff 190.50 scf sf
3870 4365 m
gs 1 -1 sc (K1 =) col0 sh gr
/Times-Roman ff 190.50 scf sf
3870 4590 m
gs 1 -1 sc (phi1 =) col0 sh gr
/Times-Roman ff 190.50 scf sf
5760 4365 m
gs 1 -1 sc (K2 =) col7 sh gr
/Times-Roman ff 190.50 scf sf
5760 4545 m
gs 1 -1 sc (phi2 =) col7 sh gr
/Times-Roman ff 190.50 scf sf
2700 4590 m
gs 1 -1 sc (300 m) col0 sh gr
/Times-Roman ff 190.50 scf sf
5085 5490 m
gs 1 -1 sc (600 m) col0 sh gr
% here ends figure;
$F2psEnd
rs
showpage
%%Trailer
%EOF

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,818 @@
%!PS-Adobe-3.0 EPSF-3.0
%%Creator: inkscape 0.45.1
%%Pages: 1
%%Orientation: Portrait
%%BoundingBox: -32 -17 872 181
%%HiResBoundingBox: -32.663784 -17.447649 871.52299 180.7467
%%EndComments
%%Page: 1 1
0 208 translate
0.8 -0.8 scale
0 0 0 setrgbcolor
[] 0 setdash
1 setlinewidth
0 setlinejoin
0 setlinecap
gsave [1 0 0 1 0 0] concat
gsave [1 0 0 1 93.027596 35.692988] concat
0 0 0 setrgbcolor
[] 0 setdash
3 setlinewidth
1 setlinejoin
0 setlinecap
newpath
109.14135 54.647896 moveto
629.14434 54.647896 lineto
629.93493 54.647896 630.5714 55.284364 630.5714 56.074955 curveto
630.5714 158.93512 lineto
630.5714 159.72571 629.93493 160.36218 629.14434 160.36218 curveto
109.14135 160.36218 lineto
108.35076 160.36218 107.71429 159.72571 107.71429 158.93512 curveto
107.71429 56.074955 lineto
107.71429 55.284364 108.35076 54.647896 109.14135 54.647896 curveto
closepath
stroke
0 0 0 setrgbcolor
[3 1.5] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
265 54.814998 moveto
265 160.20923 lineto
stroke
gsave
0.50980395 0.1882353 0.06666667 setrgbcolor
newpath
268.18165 55.866428 moveto
626.36676 55.866428 lineto
627.81029 55.866428 628.97241 57.028551 628.97241 58.472085 curveto
628.97241 156.23226 lineto
628.97241 157.67579 627.81029 158.83792 626.36676 158.83792 curveto
268.18165 158.83792 lineto
266.73811 158.83792 265.57599 157.67579 265.57599 156.23226 curveto
265.57599 58.472085 lineto
265.57599 57.028551 266.73811 55.866428 268.18165 55.866428 curveto
closepath
fill
grestore
gsave [1 0 0 1 4 0] concat
gsave [1 0 0 1 236.47088 0.080825925] concat
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
127.62019 161.05119 moveto
106.25152 185.86643 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
146.86421 161.09869 moveto
125.49554 185.91393 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
166.83819 160.94358 moveto
145.46952 185.75882 lineto
stroke
gsave [1 0 0 1 59.384214 -0.077555686] concat
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
127.62019 161.05119 moveto
106.25152 185.86643 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
146.86421 161.09869 moveto
125.49554 185.91393 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
166.83819 160.94358 moveto
145.46952 185.75882 lineto
stroke
grestore
grestore
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
483.17157 161.25369 moveto
461.8029 186.06893 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
502.41559 161.30119 moveto
481.04692 186.11643 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
522.38957 161.14608 moveto
501.0209 185.96132 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
542.55578 161.17613 moveto
521.18711 185.99137 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
561.7998 161.22363 moveto
540.43113 186.03887 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
581.77378 161.06852 moveto
560.40511 185.88376 lineto
stroke
gsave [1 0 0 1 -1.0160692 0.080825925] concat
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
127.62019 161.05119 moveto
106.25152 185.86643 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
146.86421 161.09869 moveto
125.49554 185.91393 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
166.83819 160.94358 moveto
145.46952 185.75882 lineto
stroke
gsave [1 0 0 1 59.384214 -0.077555686] concat
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
127.62019 161.05119 moveto
106.25152 185.86643 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
146.86421 161.09869 moveto
125.49554 185.91393 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
166.83819 160.94358 moveto
145.46952 185.75882 lineto
stroke
grestore
gsave [1 0 0 1 119.0805 0.1216738] concat
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
127.62019 161.05119 moveto
106.25152 185.86643 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
146.86421 161.09869 moveto
125.49554 185.91393 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
166.83819 160.94358 moveto
145.46952 185.75882 lineto
stroke
gsave [1 0 0 1 59.384214 -0.077555686] concat
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
127.62019 161.05119 moveto
106.25152 185.86643 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
146.86421 161.09869 moveto
125.49554 185.91393 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
166.83819 160.94358 moveto
145.46952 185.75882 lineto
stroke
grestore
grestore
grestore
gsave [1 0 0 1 39.791519 0.077559725] concat
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
561.7998 161.22363 moveto
540.43113 186.03887 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
581.77378 161.06852 moveto
560.40511 185.88376 lineto
stroke
grestore
grestore
gsave [1 0 0 1 6.657105 -131.88046] concat
gsave [1 0 0 1 236.47088 0.080825925] concat
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
127.62019 161.05119 moveto
106.25152 185.86643 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
146.86421 161.09869 moveto
125.49554 185.91393 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
166.83819 160.94358 moveto
145.46952 185.75882 lineto
stroke
gsave [1 0 0 1 59.384214 -0.077555686] concat
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
127.62019 161.05119 moveto
106.25152 185.86643 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
146.86421 161.09869 moveto
125.49554 185.91393 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
166.83819 160.94358 moveto
145.46952 185.75882 lineto
stroke
grestore
grestore
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
483.17157 161.25369 moveto
461.8029 186.06893 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
502.41559 161.30119 moveto
481.04692 186.11643 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
522.38957 161.14608 moveto
501.0209 185.96132 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
542.55578 161.17613 moveto
521.18711 185.99137 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
561.7998 161.22363 moveto
540.43113 186.03887 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
581.77378 161.06852 moveto
560.40511 185.88376 lineto
stroke
gsave [1 0 0 1 -1.0160692 0.080825925] concat
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
127.62019 161.05119 moveto
106.25152 185.86643 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
146.86421 161.09869 moveto
125.49554 185.91393 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
166.83819 160.94358 moveto
145.46952 185.75882 lineto
stroke
gsave [1 0 0 1 59.384214 -0.077555686] concat
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
127.62019 161.05119 moveto
106.25152 185.86643 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
146.86421 161.09869 moveto
125.49554 185.91393 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
166.83819 160.94358 moveto
145.46952 185.75882 lineto
stroke
grestore
gsave [1 0 0 1 119.0805 0.1216738] concat
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
127.62019 161.05119 moveto
106.25152 185.86643 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
146.86421 161.09869 moveto
125.49554 185.91393 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
166.83819 160.94358 moveto
145.46952 185.75882 lineto
stroke
gsave [1 0 0 1 59.384214 -0.077555686] concat
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
127.62019 161.05119 moveto
106.25152 185.86643 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
146.86421 161.09869 moveto
125.49554 185.91393 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
166.83819 160.94358 moveto
145.46952 185.75882 lineto
stroke
grestore
grestore
grestore
gsave [1 0 0 1 39.791519 0.077559725] concat
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
561.7998 161.22363 moveto
540.43113 186.03887 lineto
stroke
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
581.77378 161.06852 moveto
560.40511 185.88376 lineto
stroke
grestore
grestore
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
105.93588 217.9543 moveto
151.7385 217.33432 lineto
stroke
gsave [-1.6498489 0.022332201 -0.022332201 -1.6498489 150.08865 217.35665] concat
gsave
0 0 0 setrgbcolor
newpath
8.7185878 4.0337352 moveto
-2.2072895 0.016013256 lineto
8.7185884 -4.0017078 lineto
6.97309 -1.6296469 6.9831476 1.6157441 8.7185878 4.0337352 curveto
closepath
eofill
grestore
grestore
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
106.54211 218.35483 moveto
106.86591 172.54916 lineto
stroke
gsave [-0.011663548 1.6499588 -1.6499588 -0.011663548 106.85425 174.19912] concat
gsave
0 0 0 setrgbcolor
newpath
8.7185878 4.0337352 moveto
-2.2072895 0.016013256 lineto
8.7185884 -4.0017078 lineto
6.97309 -1.6296469 6.9831476 1.6157441 8.7185878 4.0337352 curveto
closepath
eofill
grestore
grestore
gsave [1 0 0 1 -209.68808 -53.894489] concat
gsave [1 0 0 -1 348.4375 299.18834] concat
gsave
/newlatin1font {findfont dup length dict copy dup /Encoding ISOLatin1Encoding put definefont} def
/LucidaBright-ISOLatin1 /LucidaBright newlatin1font
24 scalefont
setfont
0 0 0 setrgbcolor
newpath
0 0 moveto
(x) show
grestore
grestore
grestore
gsave [1 0 0 1 -266.24459 -115.33296] concat
gsave [1 0 0 -1 348.4375 299.18834] concat
gsave
/LucidaBright-ISOLatin1 findfont
24 scalefont
setfont
0 0 0 setrgbcolor
newpath
0 0 moveto
(y) show
grestore
grestore
grestore
gsave [1 0 0 1 -482.72842 -206.03089] concat
gsave [1 0 0 -1 348.4375 299.18834] concat
gsave
/LucidaBright-ISOLatin1 findfont
24 scalefont
setfont
0 0 0 setrgbcolor
newpath
0 0 moveto
(p_w = 2 x 10^5 [Pa]) show
grestore
grestore
grestore
gsave [1 0 0 1 -482.97404 -169.14546] concat
gsave [1 0 0 -1 348.4375 299.18834] concat
gsave
/LucidaBright-ISOLatin1 findfont
24 scalefont
setfont
0 0 0 setrgbcolor
newpath
0 0 moveto
(S_n = 0) show
grestore
grestore
grestore
gsave [1 0 0 1 317.23412 -207.53706] concat
gsave [1 0 0 -1 348.4375 299.18834] concat
gsave
/LucidaBright-ISOLatin1 findfont
24 scalefont
setfont
0 0 0 setrgbcolor
newpath
0 0 moveto
(q_w = 0 [kg/m^2s]) show
grestore
grestore
grestore
gsave [1 0 0 1 318.18473 -163.20014] concat
gsave [1 0 0 -1 348.4375 299.18834] concat
gsave
/LucidaBright-ISOLatin1 findfont
24 scalefont
setfont
0 0 0 setrgbcolor
newpath
0 0 moveto
(q_n = -3 x 10^-4 [kg/m^2s]) show
grestore
grestore
grestore
gsave
0.66666669 0.63921571 1 setrgbcolor
newpath
111.72864 55.385635 moveto
261.40382 55.385635 lineto
262.85783 55.385635 264.02838 56.556191 264.02838 58.010199 curveto
264.02838 156.47972 lineto
264.02838 157.93372 262.85783 159.10428 261.40382 159.10428 curveto
111.72864 159.10428 lineto
110.27464 159.10428 109.10408 157.93372 109.10408 156.47972 curveto
109.10408 58.010199 lineto
109.10408 56.556191 110.27464 55.385635 111.72864 55.385635 curveto
closepath
fill
grestore
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
76.75 108.48518 moveto
137.23061 108.48518 lineto
stroke
gsave [-1.65 0 0 -1.65 135.58061 108.48518] concat
gsave
0 0 0 setrgbcolor
newpath
8.7185878 4.0337352 moveto
-2.2072895 0.016013256 lineto
8.7185884 -4.0017078 lineto
6.97309 -1.6296469 6.9831476 1.6157441 8.7185878 4.0337352 curveto
closepath
eofill
grestore
grestore
0 0 0 setrgbcolor
[] 0 setdash
1.5 setlinewidth
0 setlinejoin
0 setlinecap
newpath
598.47643 107.48605 moveto
658.95704 107.48605 lineto
stroke
gsave [-1.65 0 0 -1.65 657.30704 107.48605] concat
gsave
0 0 0 setrgbcolor
newpath
8.7185878 4.0337352 moveto
-2.2072895 0.016013256 lineto
8.7185884 -4.0017078 lineto
6.97309 -1.6296469 6.9831476 1.6157441 8.7185878 4.0337352 curveto
closepath
eofill
grestore
grestore
gsave [1 0 0 1 -52.189782 -204.20014] concat
gsave [1 0 0 -1 348.4375 299.18834] concat
gsave
/LucidaBright-ISOLatin1 findfont
24 scalefont
setfont
0 0 0 setrgbcolor
newpath
0 0 moveto
(p_w_initial = 2 x 10^5 [Pa]) show
grestore
grestore
grestore
gsave [1 0 0 1 -52.436547 -169.40732] concat
gsave [1 0 0 -1 348.4375 299.18834] concat
gsave
/LucidaBright-ISOLatin1 findfont
24 scalefont
setfont
0 0 0 setrgbcolor
newpath
0 0 moveto
(S_n_initial = 0) show
grestore
grestore
grestore
gsave [1 0 0 1 -24.043935 -282.84055] concat
gsave [1 0 0 -1 348.4375 299.18834] concat
gsave
/LucidaBright-ISOLatin1 findfont
24 scalefont
setfont
0 0 0 setrgbcolor
newpath
0 0 moveto
(no flow) show
grestore
grestore
grestore
gsave [1 0 0 1 -24.00547 -81.002179] concat
gsave [1 0 0 -1 348.4375 299.18834] concat
gsave
/LucidaBright-ISOLatin1 findfont
24 scalefont
setfont
0 0 0 setrgbcolor
newpath
0 0 moveto
(no flow) show
grestore
grestore
grestore
gsave [1 0 0 1 -234.24002 -167.99702] concat
gsave [1 0 0 -1 348.4375 299.18834] concat
gsave
/LucidaBright-ISOLatin1 findfont
24 scalefont
setfont
0 0 0 setrgbcolor
newpath
0 0 moveto
(water) show
grestore
grestore
grestore
gsave [1 0 0 1 246.87279 -166.71041] concat
gsave [1 0 0 -1 348.4375 299.18834] concat
gsave
/LucidaBright-ISOLatin1 findfont
24 scalefont
setfont
0 0 0 setrgbcolor
newpath
0 0 moveto
(oil) show
grestore
grestore
grestore
grestore
grestore
showpage
%%EOF

View File

@ -0,0 +1,41 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This file has been autogenerated from the LaTeX part of the %
% doxygen documentation; DO NOT EDIT IT! Change the model's .hh %
% file instead!! %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The black-\/oil model is a three-\/phase, three-\/component model widely used for oil reservoir simulation. The phases are denoted by lower index $\alpha \in \{ w, g, o \}$ (\char`\"{}water\char`\"{}, \char`\"{}gas\char`\"{} and \char`\"{}oil\char`\"{}) and the components by upper index $\kappa \in \{ W, G, O \}$ (\char`\"{}\-Water\char`\"{}, \char`\"{}\-Gas\char`\"{} and \char`\"{}\-Oil\char`\"{}). The model assumes partial miscibility\-:
\begin{itemize}
\item Water and the gas phases are immisicible and are assumed to be only composed of the water and gas components respectively-\/
\item The oil phase is assumed to be a mixture of the gas and the oil components.
\end{itemize}
The densities of the phases are determined by so-\/called {\itshape formation volume factors}\-:
\[ B_\alpha := \frac{\varrho_\alpha(1\,\text{bar})}{\varrho_\alpha(p_\alpha)} \]
Since the gas and water phases are assumed to be immiscible, this is sufficint to calculate their density. For the formation volume factor of the the oil phase $B_o$ determines the density of {\itshape saturated} oil, i.\-e. the density of the oil phase if some gas phase is present.
The composition of the oil phase is given by the {\itshape gas formation factor} $R_s$, which defined as the volume of gas at atmospheric pressure that is dissolved in saturated oil at a given pressure\-:
\[ R_s := \frac{x_o^G(p)\,\varrho_{mol,o}(p)}{\varrho_g(1\,\text{bar})}\;. \]
This allows to calculate all quantities required for the mass-\/conservation equations for each component, i.\-e.
\[ \sum_\alpha \frac{\partial\;\phi c_\alpha^\kappa S_\alpha }{\partial t} - \sum_\alpha \text{div} \left\{ c_\alpha^\kappa \mathbf{v}_\alpha \right\} - q^\kappa = 0 \;, \] where $\mathrm{v}_\alpha$ is the filter velocity of the phase $\alpha$.
By default $\mathrm{v}_\alpha$ is determined by using the standard multi-\/phase Darcy approach, i.\-e. \[ \mathbf{v}_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mathbf{K} \left(\text{grad}\, p_\alpha - \varrho_{\alpha} \mathbf{g} \right) \;, \] although the actual approach which is used can be specified via the {\ttfamily Velocity\-Module} property. For example, the velocity model can by changed to the Forchheimer approach by
\begin{lstlisting}[style=eWomsCode]
SET_TYPE_PROP(MyProblemTypeTag, VelocityModule,
Ewoms::BoxForchheimerVelocityModule<TypeTag>);
\end{lstlisting}
The primary variables used by this model are\-:
\begin{itemize}
\item The pressure of the phase with the lowest index
\item The two saturations of the phases with the lowest indices
\end{itemize}

View File

@ -0,0 +1,35 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This file has been autogenerated from the LaTeX part of the %
% doxygen documentation; DO NOT EDIT IT! Change the model's .hh %
% file instead!! %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A generic compositional multi-\/phase model using primary-\/variable switching.
This model assumes a flow of $M \geq 1$ fluid phases $\alpha$, each of which is assumed to be a mixture $N \geq M$ chemical species (denoted by the upper index $\kappa$).
By default, the standard multi-\/phase Darcy approach is used to determine the velocity, i.\-e. \[ \mathbf{v}_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mathbf{K} \left(\text{grad}\, p_\alpha - \varrho_{\alpha} \mathbf{g} \right) \;, \] although the actual approach which is used can be specified via the {\ttfamily Velocity\-Module} property. For example, the velocity model can by changed to the Forchheimer approach by
\begin{lstlisting}[style=eWomsCode]
SET_TYPE_PROP(MyProblemTypeTag, VelocityModule,
Ewoms::BoxForchheimerVelocityModule<TypeTag>);
\end{lstlisting}
The core of the model is the conservation mass of each component by means of the equation \[ \sum_\alpha \frac{\partial\;\phi c_\alpha^\kappa S_\alpha }{\partial t} - \sum_\alpha \text{div} \left\{ c_\alpha^\kappa \mathbf{v}_\alpha \right\} - q^\kappa = 0 \;. \]
To determine the quanties that occur in the equations above, this model uses {\itshape flash calculations}. A flash solver starts with the total mass or molar mass per volume for each component and, calculates the compositions, saturations and pressures of all phases at a given temperature. For this the flash solver has to use some model assumptions internally. (Often these are the same primary variable switching or N\-C\-P assumptions as used by the other fully implicit compositional multi-\/phase models provided by e\-Woms.)
Using flash calculations for the flow model has some disadvantages\-:
\begin{itemize}
\item The accuracy of the flash solver needs to be sufficient to calculate the parital derivatives using numerical differentiation which are required for the Newton scheme.
\item Flash calculations tend to be quite computationally expensive and are often numerically unstable.
\end{itemize}
It is thus adviced to increase the target tolerance of the Newton scheme or a to use type for scalar values which exhibits higher precision than the standard {\ttfamily double} (e.\-g. {\ttfamily quad}) if this model ought to be used.
The model uses the following primary variables\-:
\begin{itemize}
\item The total molar concentration of each component\-: $c^\kappa = \sum_\alpha S_\alpha x_\alpha^\kappa \rho_{mol, \alpha}$
\item The absolute temperature \$\-T\$ in Kelvins if the energy equation enabled.
\end{itemize}

View File

@ -0,0 +1,24 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This file has been autogenerated from the LaTeX part of the %
% doxygen documentation; DO NOT EDIT IT! Change the model's .hh %
% file instead!! %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
This model multi-\/phase flow of $M > 0$ immiscible fluids $\alpha$. By default, the standard multi-\/phase Darcy approach is used to determine the velocity, i.\-e. \[ \mathbf{v}_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mathbf{K} \left(\text{grad}\, p_\alpha - \varrho_{\alpha} \mathbf{g} \right) \;, \] although the actual approach which is used can be specified via the {\ttfamily Velocity\-Module} property. For example, the velocity model can by changed to the Forchheimer approach by
\begin{lstlisting}[style=eWomsCode]
SET_TYPE_PROP(MyProblemTypeTag, VelocityModule,
Ewoms::BoxForchheimerVelocityModule<TypeTag>);
\end{lstlisting}
The core of the model is the conservation mass of each component by means of the equation \[ \frac{\partial\;\phi S_\alpha \rho_\alpha }{\partial t} - \text{div} \left\{ \rho_\alpha \mathbf{v}_\alpha \right\} - q_\alpha = 0 \;. \]
These equations are discretized by a fully-\/coupled vertex centered finite volume (box) scheme as spatial and the implicit Euler method as time discretization.
The model uses the following primary variables\-:
\begin{itemize}
\item The pressure $p_0$ in Pascal of the phase with the lowest index
\item The saturations $S_\alpha$ of the $M - 1$ phases that exhibit the lowest indices
\item The absolute temperature $T$ in Kelvin if energy is conserved via the energy equation
\end{itemize}

View File

@ -0,0 +1,37 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This file has been autogenerated from the LaTeX part of the %
% doxygen documentation; DO NOT EDIT IT! Change the model's .hh %
% file instead!! %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
This model implements a $M$-\/phase flow of a fluid mixture composed of $N$ chemical species. The phases are denoted by lower index $\alpha \in \{ 1, \dots, M \}$. All fluid phases are mixtures of $N \geq M - 1$ chemical species which are denoted by the upper index $\kappa \in \{ 1, \dots, N \} $.
By default, the standard multi-\/phase Darcy approach is used to determine the velocity, i.\-e. \[ \mathbf{v}_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mathbf{K} \left(\text{grad}\, p_\alpha - \varrho_{\alpha} \mathbf{g} \right) \;, \] although the actual approach which is used can be specified via the {\ttfamily Velocity\-Module} property. For example, the velocity model can by changed to the Forchheimer approach by
\begin{lstlisting}[style=eWomsCode]
SET_TYPE_PROP(MyProblemTypeTag, VelocityModule,
Ewoms::BoxForchheimerVelocityModule<TypeTag>);
\end{lstlisting}
The core of the model is the conservation mass of each component by means of the equation \[ \sum_\alpha \frac{\partial\;\phi c_\alpha^\kappa S_\alpha }{\partial t} - \sum_\alpha \text{div} \left\{ c_\alpha^\kappa \mathbf{v}_\alpha \right\} - q^\kappa = 0 \;. \]
For the missing $M$ model assumptions, the model uses non-\/linear complementarity functions. These are based on the observation that if a fluid phase is not present, the sum of the mole fractions of this fluid phase is smaller than $1$, i.\-e. \[ \forall \alpha: S_\alpha = 0 \implies \sum_\kappa x_\alpha^\kappa \leq 1 \]
Also, if a fluid phase may be present at a given spatial location its saturation must be non-\/negative\-: \[ \forall \alpha: \sum_\kappa x_\alpha^\kappa = 1 \implies S_\alpha \geq 0 \]
Since at any given spatial location, a phase is always either present or not present, one of the strict equalities on the right hand side is always true, i.\-e. \[ \forall \alpha: S_\alpha \left( \sum_\kappa x_\alpha^\kappa - 1 \right) = 0 \] always holds.
These three equations constitute a non-\/linear complementarity problem, which can be solved using so-\/called non-\/linear complementarity functions $\Phi(a, b)$. Such functions have the property \[\Phi(a,b) = 0 \iff a \geq0 \land b \geq0 \land a \cdot b = 0 \]
Several non-\/linear complementarity functions have been suggested, e.\-g. the Fischer-\/\-Burmeister function \[ \Phi(a,b) = a + b - \sqrt{a^2 + b^2} \;. \] This model uses \[ \Phi(a,b) = \min \{a, b \}\;, \] because of its piecewise linearity.
These equations are then discretized using a fully-\/implicit vertex centered finite volume scheme (often known as 'box'-\/scheme) for spatial discretization and the implicit Euler method as temporal discretization.
The model assumes local thermodynamic equilibrium and uses the following primary variables\-:
\begin{itemize}
\item The pressure of the first phase $p_1$
\item The component fugacities $f^1, \dots, f^{N}$
\item The saturations of the first $M-1$ phases $S_1, \dots, S_{M-1}$
\item Temperature $T$ if the energy equation is enabled
\end{itemize}

View File

@ -0,0 +1,51 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This file has been autogenerated from the LaTeX part of the %
% doxygen documentation; DO NOT EDIT IT! Change the model's .hh %
% file instead!! %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
This model assumes a flow of $M \geq 1$ fluid phases $\alpha$, each of which is assumed to be a mixture $N \geq M$ chemical species $\kappa$.
By default, the standard multi-\/phase Darcy approach is used to determine the velocity, i.\-e. \[ \mathbf{v}_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mathbf{K} \left(\text{grad}\, p_\alpha - \varrho_{\alpha} \mathbf{g} \right) \;, \] although the actual approach which is used can be specified via the {\ttfamily Velocity\-Module} property. For example, the velocity model can by changed to the Forchheimer approach by
\begin{lstlisting}[style=eWomsCode]
SET_TYPE_PROP(MyProblemTypeTag, VelocityModule,
Ewoms::BoxForchheimerVelocityModule<TypeTag>);
\end{lstlisting}
The core of the model is the conservation mass of each component by means of the equation \[ \sum_\alpha \frac{\partial\;\phi c_\alpha^\kappa S_\alpha }{\partial t} - \sum_\alpha \text{div} \left\{ c_\alpha^\kappa \mathbf{v}_\alpha \right\} - q^\kappa = 0 \;. \]
To close the system mathematically, $M$ model equations are also required. This model uses the primary variable switching assumptions, which are given by\-: \[ 0 \stackrel{!}{=} f_\alpha = \left\{ \begin{array}{cl} S_\alpha & \quad \text{if phase }\alpha\text{ is not present} \\ 1 - \sum_\kappa x_\alpha^\kappa & \quad \text{else} \end{array} \right. \]
To make this approach applicable, a pseudo primary variable {\itshape phase presence} has to be introduced. Its purpose is to specify for each phase whether it is present or not. It is a {\itshape pseudo} primary variable because it is not directly considered when linearizing the system in the Newton method, but after each Newton iteration, it gets updated like the \char`\"{}real\char`\"{} primary variables. The following rules are used for this update procedure\-:
\begin{itemize}
\item If phase $\alpha$ is present according to the pseudo primary variable, but $S_\alpha < 0$ after the Newton update, consider the phase $\alpha$ disappeared for the next iteration and use the set of primary variables which correspond to the new phase presence.
\item If phase $\alpha$ is not present according to the pseudo primary variable, but the sum of the component mole fractions in the phase is larger than 1, i.\-e. $\sum_\kappa x_\alpha^\kappa > 1$, consider the phase $\alpha$ present in the the next iteration and update the set of primary variables to make it consistent with the new phase presence.
\item In all other cases don't modify the phase presence for phase $\alpha$.
\end{itemize}
The model always requires $N$ primary variables, but their interpretation is dependent on the phase presence\-:
\begin{itemize}
\item The first primary variable is always interpreted as the pressure of the phase with the lowest index $PV_0 = p_0$.
\item Then, $M - 1$ \char`\"{}switching primary variables\char`\"{} follow, which are interpreted depending in the presence of the first $M-1$ phases\-: If phase $\alpha$ is present, its saturation $S_\alpha = PV_i$ is used as primary variable; if it is not present, the mole fraction $PV_i = x_{\alpha^\star}^\alpha$ of the component with index $\alpha$ in the phase with the lowest index that is present $\alpha^\star$ is used instead.
\item Finally, the mole fractions of the $N-M$ components with the largest index in the phase with the lowest index that is present $x_{\alpha^\star}^\kappa$ are used as primary variables.
\end{itemize}
This model is then discretized using a fully-\/coupled vertex centered finite volume (box) scheme as spatial and the implicit Euler method as temporal discretization.

View File

@ -0,0 +1,12 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This file has been autogenerated from the LaTeX part of the %
% doxygen documentation; DO NOT EDIT IT! Change the model's .hh %
% file instead!! %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
In the unsaturated zone, Richards' equation is frequently used to approximate the water distribution above the groundwater level. It can be derived from the two-\/phase equations, i.\-e. \[ \frac{\partial\;\phi S_\alpha \rho_\alpha}{\partial t} - \text{div} \left\{ \rho_\alpha \frac{k_{r\alpha}}{\mu_\alpha}\; \mathbf{K}\; \textbf{grad}\left[ p_\alpha - g\rho_\alpha \right] \right\} = q_\alpha, \] where $\alpha \in \{w, n\}$ is the index of the fluid phase, $\rho_\alpha$ is the fluid density, $S_\alpha$ is the fluid saturation, $\phi$ is the porosity of the soil, $k_{r\alpha}$ is the relative permeability for the fluid, $\mu_\alpha$ is the fluid's dynamic viscosity, $\mathbf{K}$ is the intrinsic permeability tensor, $p_\alpha$ is the fluid phase pressure and $g$ is the potential of the gravity field.
In contrast to the \char`\"{}full\char`\"{} two-\/phase model, the Richards model assumes that the non-\/wetting fluid is gas and that it thus exhibits a much lower viscosity than the (liquid) wetting phase. (This assumption is quite realistic in many applications\-: For example, at atmospheric pressure and at room temperature, the viscosity of air is only about $1\%$ of the viscosity of liquid water.) As a consequence, the $\frac{k_{r\alpha}}{\mu_\alpha}$ term typically is much larger for the gas phase than for the wetting phase. Using this reasoning, the Richards model assumes that $\frac{k_{rn}}{\mu_n}$ is infinitely large compared to the same term of the liquid phase. This implies that the pressure of the gas phase is equivalent to the static pressure distribution and that therefore, mass conservation only needs to be considered for the liquid phase.
The model thus choses the absolute pressure of the wetting phase $p_w$ as its only primary variable. The wetting phase saturation is calculated using the inverse of the capillary pressure, i.\-e. \[ S_w = p_c^{-1}(p_n - p_w) \] holds, where $p_n$ is a reference pressure given by the problem's {\ttfamily reference\-Pressure()} method. Nota bene, that the last step assumes that the capillary pressure-\/saturation curve can be uniquely inverted, i.\-e. it is not possible to set the capillary pressure to zero if the Richards model ought to be used!

View File

@ -0,0 +1,12 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This file has been autogenerated from the LaTeX part of the %
% doxygen documentation; DO NOT EDIT IT! Change the model's .hh %
% file instead!! %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
This model implements Navier-\/\-Stokes flow of a single fluid. By default, it solves the momentum balance of the time-\/dependent Stokes equations, i.\-e. \[ \frac{\partial \left(\varrho\,\mathbf{v}\right)}{\partial t} + \boldsymbol{\nabla} p - \nabla \cdot \left( \mu \left(\boldsymbol{\nabla} \mathbf{v} + \boldsymbol{\nabla} \mathbf{v}^T\right) \right) - \varrho\,\mathbf{g} = 0\;, \] and the mass balance equation \[ \frac{\partial \varrho}{\partial t} + \nabla \cdot\left(\varrho\,\mathbf{v}\right) - q = 0 \;. \]
If the property {\ttfamily Enable\-Navier\-Stokes} is set to {\ttfamily true}, an additional convective momentum flux term (Navier term) gets included into the momentum conservation equations which allows to capture turbolent flow regimes. This additional term is given by \[ \varrho \left(\mathbf{v} \cdot \boldsymbol{\nabla} \right) \mathbf{v} \;. \]
These equations are discretized by a fully-\/coupled vertex-\/centered finite volume (box) scheme in space and using the implicit Euler method in time. Be aware, that this discretization scheme is quite unstable for the Navier-\/\-Stokes equations and quickly leads to unphysical oscillations in the calculated solution. We intend to use a more appropriate discretization scheme in the future, though.

733
doc/handbook/SVG/box_disc.svg Executable file
View File

@ -0,0 +1,733 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="1052.3622"
height="744.09448"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.48.0 r9654"
version="1.0"
sodipodi:docname="box_disc.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Sstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Sstart"
style="overflow:visible">
<path
id="path3538"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
transform="scale(0.2) translate(6,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Mstart"
style="overflow:visible">
<path
id="path3532"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
transform="scale(0.4) translate(10,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Mend"
style="overflow:visible;">
<path
id="path3727"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
transform="scale(0.4) rotate(180) translate(10,0)" />
</marker>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.74"
inkscape:cx="526.18109"
inkscape:cy="381.46306"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="1280"
inkscape:window-height="963"
inkscape:window-x="0"
inkscape:window-y="17"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
id="grid2385"
visible="true"
enabled="true" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<flowRoot
xml:space="preserve"
id="flowRoot5192"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
transform="translate(312.64918,-277.68247)"><flowRegion
id="flowRegion5194"><rect
id="rect5196"
width="83.980377"
height="54.214508"
x="509.61661"
y="493.35226"
style="fill:#0000ff;fill-opacity:1" /></flowRegion><flowPara
id="flowPara5198">scv</flowPara></flowRoot> <flowRoot
xml:space="preserve"
id="flowRoot5200"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
transform="translate(278.08736,-204.1169)"><flowRegion
id="flowRegion5202"><rect
id="rect5204"
width="29.818018"
height="28.462643"
x="608.55817"
y="444.55917"
style="fill:#0000ff;fill-opacity:1" /></flowRegion><flowPara
id="flowPara5206"
style="font-size:20px;fill:#0000ff;fill-opacity:1">i</flowPara></flowRoot> <flowRoot
xml:space="preserve"
id="flowRoot5216"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
transform="translate(281.25248,-235.98661)"><flowRegion
id="flowRegion5218"><rect
id="rect5220"
width="29.818018"
height="28.462643"
x="608.55817"
y="444.55917"
style="fill:#0000ff;fill-opacity:1" /></flowRegion><flowPara
id="flowPara5222"
style="font-size:20px;fill:#0000ff;fill-opacity:1">k</flowPara></flowRoot> <g
id="g3686">
<rect
ry="1.2165556"
y="124.64518"
x="59.951752"
height="399.42368"
width="399.94101"
id="rect2383"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path2389"
d="M 260,123.33807 L 258.8744,525.88098"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
<path
id="path2391"
d="M 60,324.09448 L 460,324.09448"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<g
id="g5054">
<path
id="path3163"
d="M 161.28824,64.094482 L 160,586.87233"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:12, 3;stroke-dashoffset:0;stroke-opacity:1" />
<path
id="path3165"
d="M -1.3553634,224.09448 L 520,224.99032"
style="fill:#800080;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;marker-start:none;stroke-miterlimit:4;stroke-dasharray:12, 3;stroke-dashoffset:0;stroke-opacity:1" />
<path
id="path3676"
d="M 0.90744595,424.09448 L 522.26286,424.99032"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;marker-start:none;stroke-miterlimit:4;stroke-dasharray:12, 3;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:12, 3;stroke-dashoffset:0;stroke-opacity:1"
d="M 362.39396,64.094482 L 361.10572,586.87233"
id="path3678" />
<flowRoot
xml:space="preserve"
id="flowRoot3695"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
transform="translate(-487.86472,28.082659)"><flowRegion
id="flowRegion3697"><rect
id="rect3699"
width="242.61003"
height="29.817987"
x="440.4931"
y="25.751904" /></flowRegion><flowPara
id="flowPara3701"
style="font-size:24px">FE mesh</flowPara></flowRoot> <flowRoot
xml:space="preserve"
id="flowRoot3703"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
transform="translate(-273.66406,-5.987759)"><flowRegion
id="flowRegion3705"><rect
id="rect3707"
width="261.58514"
height="31.173353"
x="440.4931"
y="25.751904" /></flowRegion><flowPara
id="flowPara3709"
style="font-size:24px">secondary FV mesh</flowPara></flowRoot> <path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 78.265175,87.068982 L 103.04528,117.84893"
id="path3711" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 304.65694,51.290483 L 350.68269,98.802518"
id="path3713" />
<path
sodipodi:type="arc"
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path5008"
sodipodi:cx="261.58511"
sodipodi:cy="329.3533"
sodipodi:rx="13.553634"
sodipodi:ry="13.553634"
d="M 275.13875,329.3533 A 13.553634,13.553634 0 1 1 248.03148,329.3533 A 13.553634,13.553634 0 1 1 275.13875,329.3533 z"
transform="translate(0,-6)" />
<flowRoot
xml:space="preserve"
id="flowRoot5010"
style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
transform="translate(-122.80934,-5.4214534)"><flowRegion
id="flowRegion5012"><rect
id="rect5014"
width="86.743225"
height="32.528732"
x="295.46921"
y="284.62631"
style="font-size:24px" /></flowRegion><flowPara
id="flowPara5016">node i</flowPara></flowRoot> <g
id="g5069">
<flowRoot
transform="translate(-56.925781,-169.42042)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
id="flowRoot5018"
xml:space="preserve"><flowRegion
id="flowRegion5020"><rect
y="493.35226"
x="509.61661"
height="54.214523"
width="66.412804"
id="rect5022" /></flowRegion><flowPara
id="flowPara5024">E</flowPara></flowRoot> <flowRoot
transform="translate(-119.27198,-96.941526)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
id="flowRoot5026"
xml:space="preserve"><flowRegion
id="flowRegion5028"><rect
y="444.55917"
x="608.55817"
height="28.462643"
width="29.818018"
id="rect5030" /></flowRegion><flowPara
style="font-size:20px"
id="flowPara5032">k</flowPara></flowRoot> </g>
<rect
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:8;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect5034"
width="199.23842"
height="197.88306"
x="261.58511"
y="325.2872"
ry="1.2165556" />
<rect
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#0000ff;stroke-width:8;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect5036"
width="199.23842"
height="197.88306"
x="160.6929"
y="224.99031"
ry="1.2165556" />
<g
id="g5059"
transform="translate(2.7107267,0)">
<flowRoot
transform="translate(-161.31878,-270.23563)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
id="flowRoot5038"
xml:space="preserve"><flowRegion
id="flowRegion5040"><rect
style="fill:#0000ff;fill-opacity:1"
y="493.35226"
x="509.61661"
height="54.214523"
width="66.412804"
id="rect5042" /></flowRegion><flowPara
id="flowPara5044">B</flowPara></flowRoot> <flowRoot
transform="translate(-225.8806,-196.67006)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
id="flowRoot5046"
xml:space="preserve"><flowRegion
id="flowRegion5048"><rect
style="fill:#0000ff;fill-opacity:1"
y="444.55917"
x="608.55817"
height="28.462643"
width="29.818018"
id="rect5050" /></flowRegion><flowPara
style="font-size:20px;fill:#0000ff;fill-opacity:1"
id="flowPara5052">i</flowPara></flowRoot> </g>
<g
id="g5081"
transform="translate(365.08079,20.301186)">
<flowRoot
transform="translate(-56.925781,-169.42042)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
id="flowRoot5083"
xml:space="preserve"><flowRegion
id="flowRegion5085"><rect
y="493.35226"
x="509.61661"
height="54.214523"
width="66.412804"
id="rect5087" /></flowRegion><flowPara
id="flowPara5089">E</flowPara></flowRoot> <flowRoot
transform="translate(-119.27198,-96.941526)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
id="flowRoot5091"
xml:space="preserve"><flowRegion
id="flowRegion5093"><rect
y="444.55917"
x="608.55817"
height="28.462643"
width="29.818018"
id="rect5095" /></flowRegion><flowPara
style="font-size:20px"
id="flowPara5097">k</flowPara></flowRoot> </g>
<path
style="fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:2.75723743;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:11.02894999, 2.7572375;stroke-dashoffset:0;stroke-opacity:1"
d="M 588.32046,462.50936 L 858.51314,462.50936"
id="path5101" />
<path
style="fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:2.84685826;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:11.38743312, 2.84685828;stroke-dashoffset:0;stroke-opacity:1"
d="M 719.92343,327.55321 L 721.46033,588.23818"
id="path5103" />
<g
id="g5113"
transform="translate(-16.90383,274.90485)">
<rect
ry="1.2165556"
y="86.211426"
x="641.76453"
height="197.88306"
width="199.23842"
id="rect5079"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:8;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<path
transform="translate(380.41489,-48.793085)"
d="m 275.13875,329.3533 c 0,7.48547 -6.06817,13.55364 -13.55364,13.55364 -7.48546,0 -13.55363,-6.06817 -13.55363,-13.55364 0,-7.48546 6.06817,-13.55363 13.55363,-13.55363 7.48547,0 13.55364,6.06817 13.55364,13.55363 z"
sodipodi:ry="13.553634"
sodipodi:rx="13.553634"
sodipodi:cy="329.3533"
sodipodi:cx="261.58511"
id="path5105"
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
sodipodi:type="arc" />
<path
transform="translate(574.67408,-47.437724)"
d="m 275.13875,329.3533 c 0,7.48547 -6.06817,13.55364 -13.55364,13.55364 -7.48546,0 -13.55363,-6.06817 -13.55363,-13.55364 0,-7.48546 6.06817,-13.55363 13.55363,-13.55363 7.48547,0 13.55364,6.06817 13.55364,13.55363 z"
sodipodi:ry="13.553634"
sodipodi:rx="13.553634"
sodipodi:cy="329.3533"
sodipodi:cx="261.58511"
id="path5107"
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
sodipodi:type="arc" />
<path
inkscape:transform-center-y="15.053634"
transform="translate(576.67408,-244.61005)"
d="m 275.13875,329.3533 c 0,7.48547 -6.06817,13.55364 -13.55364,13.55364 -7.48546,0 -13.55363,-6.06817 -13.55363,-13.55364 0,-7.48546 6.06817,-13.55363 13.55363,-13.55363 7.48547,0 13.55364,6.06817 13.55364,13.55363 z"
sodipodi:ry="13.553634"
sodipodi:rx="13.553634"
sodipodi:cy="329.3533"
sodipodi:cx="261.58511"
id="path5109"
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
sodipodi:type="arc" />
<path
inkscape:transform-center-y="15.053634"
transform="translate(379.50176,-242.61004)"
d="m 275.13875,329.3533 c 0,7.48547 -6.06817,13.55364 -13.55364,13.55364 -7.48546,0 -13.55363,-6.06817 -13.55363,-13.55364 0,-7.48546 6.06817,-13.55363 13.55363,-13.55363 7.48547,0 13.55364,6.06817 13.55364,13.55363 z"
sodipodi:ry="13.553634"
sodipodi:rx="13.553634"
sodipodi:cy="329.3533"
sodipodi:cx="261.58511"
id="path5111"
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
sodipodi:type="arc" />
</g>
<rect
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#0000ff;stroke-width:8;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect5124"
width="199.23842"
height="197.88306"
x="620"
y="67.768166"
ry="1.2165556" />
<g
id="g5126"
transform="translate(468.83473,-158.08537)">
<flowRoot
transform="translate(-161.31878,-270.23563)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
id="flowRoot5128"
xml:space="preserve"><flowRegion
id="flowRegion5130"><rect
style="fill:#0000ff;fill-opacity:1"
y="493.35226"
x="509.61661"
height="54.214523"
width="66.412804"
id="rect5132" /></flowRegion><flowPara
id="flowPara5134">B</flowPara></flowRoot> <flowRoot
transform="translate(-225.8806,-196.67006)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
id="flowRoot5136"
xml:space="preserve"><flowRegion
id="flowRegion5138"><rect
style="fill:#0000ff;fill-opacity:1"
y="444.55917"
x="608.55817"
height="28.462643"
width="29.818018"
id="rect5140" /></flowRegion><flowPara
style="font-size:20px;fill:#0000ff;fill-opacity:1"
id="flowPara5142">i</flowPara></flowRoot> </g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.77284336;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 586.6497,164.09448 L 859.9096,164.09448"
id="path5146" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="M 721.05331,42.016264 L 718.34258,298.17994"
id="path5154" />
<flowRoot
xml:space="preserve"
id="flowRoot5158"
style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
transform="translate(388.86722,-154.7741)"><flowRegion
id="flowRegion5160"><rect
id="rect5162"
width="20.330421"
height="32.528717"
x="295.46921"
y="284.62631"
style="font-size:24px" /></flowRegion><flowPara
id="flowPara5164">i</flowPara></flowRoot> <rect
style="opacity:1;fill:#00a3ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect5186"
width="94.875458"
height="97.490631"
x="721.05334"
y="164.80521"
ry="1.1825171" />
<path
sodipodi:type="arc"
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path5188"
sodipodi:cx="261.58511"
sodipodi:cy="329.3533"
sodipodi:rx="13.553634"
sodipodi:ry="13.553634"
d="M 275.13875,329.3533 A 13.553634,13.553634 0 1 1 248.03148,329.3533 A 13.553634,13.553634 0 1 1 275.13875,329.3533 z"
transform="translate(456.75746,-165.25882)" />
<flowRoot
xml:space="preserve"
id="flowRoot5224"
style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
transform="translate(293.26953,44.832497)"><flowRegion
id="flowRegion5226"><rect
id="rect5228"
width="20.330421"
height="32.528717"
x="295.46921"
y="284.62631"
style="font-size:24px" /></flowRegion><flowPara
id="flowPara5230">i</flowPara></flowRoot> <flowRoot
xml:space="preserve"
id="flowRoot5232"
style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
transform="translate(292.0629,275.5475)"><flowRegion
id="flowRegion5234"><rect
id="rect5236"
width="20.330421"
height="32.528717"
x="295.46921"
y="284.62631"
style="font-size:24px" /></flowRegion><flowPara
id="flowPara5238">j</flowPara></flowRoot> <path
style="fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 628.24396,462.1789 L 720.40867,462.1789"
id="path5358" />
<g
id="g5398"
transform="translate(-343.58331,-18.217817)">
<flowRoot
transform="translate(364.22784,7.914998)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
id="flowRoot5362"
xml:space="preserve"><flowRegion
id="flowRegion5364"><rect
style="fill:#000000;fill-opacity:1"
y="493.35226"
x="509.61661"
height="54.214523"
width="66.412804"
id="rect5366" /></flowRegion><flowPara
id="flowPara5368">x</flowPara></flowRoot> <flowRoot
transform="translate(299.66602,81.480568)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
id="flowRoot5370"
xml:space="preserve"><flowRegion
id="flowRegion5372"><rect
style="fill:#000000;fill-opacity:1"
y="444.55917"
x="608.55817"
height="28.462643"
width="29.818018"
id="rect5374" /></flowRegion><flowPara
style="font-size:20px;fill:#000000;fill-opacity:1"
id="flowPara5376">ij</flowPara></flowRoot> <flowRoot
transform="translate(296.83114,49.610858)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
id="flowRoot5378"
xml:space="preserve"><flowRegion
id="flowRegion5380"><rect
style="fill:#000000;fill-opacity:1"
y="444.55917"
x="608.55817"
height="28.462643"
width="29.818018"
id="rect5382" /></flowRegion><flowPara
style="font-size:20px;fill:#000000;fill-opacity:1"
id="flowPara5384">k</flowPara></flowRoot> </g>
<g
id="g5450"
transform="translate(-321.60139,-88.611075)">
<flowRoot
transform="translate(330.68379,-21.17828)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
id="flowRoot5414"
xml:space="preserve"><flowRegion
id="flowRegion5416"><rect
style="fill:#0000ff;fill-opacity:1"
y="493.35226"
x="509.61661"
height="54.214508"
width="85.331734"
id="rect5418" /></flowRegion><flowPara
id="flowPara5420">e</flowPara></flowRoot> <flowRoot
transform="translate(278.12197,52.38729)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
id="flowRoot5422"
xml:space="preserve"><flowRegion
id="flowRegion5424"><rect
style="fill:#0000ff;fill-opacity:1"
y="444.55917"
x="608.55817"
height="28.462643"
width="29.818018"
id="rect5426" /></flowRegion><flowPara
style="font-size:20px;fill:#0000ff;fill-opacity:1"
id="flowPara5428">ij</flowPara></flowRoot> <flowRoot
transform="translate(275.28709,20.51758)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
id="flowRoot5430"
xml:space="preserve"><flowRegion
id="flowRegion5432"><rect
style="fill:#0000ff;fill-opacity:1"
y="444.55917"
x="608.55817"
height="28.462643"
width="29.818018"
id="rect5434" /></flowRegion><flowPara
style="font-size:20px;fill:#0000ff;fill-opacity:1"
id="flowPara5436">k</flowPara></flowRoot> </g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;marker-start:none;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 591.26887,421.518 C 596.3425,420.12834 604.10437,422.71162 610.24396,424.09448 C 616.3176,425.46249 623.65841,426.32084 629.21904,431.00554 C 640,440.08825 640.16512,442.43779 642.77268,445.91454 C 645.16174,449.09996 641.75951,451.34942 642.77268,455.40209"
id="path5464"
sodipodi:nodetypes="csssc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.79728961;stroke-linecap:butt;stroke-linejoin:miter;marker-start:none;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 588.66891,514.42274 C 595.98004,515.79437 606.94533,512.61565 615.6496,510.84144 C 624.26038,509.08628 634.70475,507.85588 642.42818,502.40286 C 657.40241,491.83054 657.52869,489.19166 661.09078,485.20028 C 664.35438,481.54336 659.39032,479.14712 660.64841,474.5687"
id="path7526"
sodipodi:nodetypes="csssc" />
<path
sodipodi:type="arc"
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path7528"
sodipodi:cx="666.89191"
sodipodi:cy="460.98639"
sodipodi:rx="8.7837839"
sodipodi:ry="10.135136"
d="M 675.67569,460.98639 A 8.7837839,10.135136 0 1 1 658.10812,460.98639 A 8.7837839,10.135136 0 1 1 675.67569,460.98639 z"
transform="translate(4,0)" />
<flowRoot
xml:space="preserve"
id="flowRoot7550"
style="font-size:24;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
transform="translate(-75.675676,-574.32432)"><flowRegion
id="flowRegion7552"><rect
id="rect7554"
width="78.37838"
height="113.51351"
x="60.81081"
y="575.17554"
style="font-size:24" /></flowRegion><flowPara
id="flowPara7556">a)</flowPara></flowRoot> <flowRoot
xml:space="preserve"
id="flowRoot7558"
style="font-size:24;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
transform="translate(472.3939,-571.93744)"><flowRegion
id="flowRegion7560"><rect
id="rect7562"
width="78.37838"
height="113.51351"
x="60.81081"
y="575.17554"
style="font-size:24" /></flowRegion><flowPara
id="flowPara7564">b)</flowPara></flowRoot> <flowRoot
xml:space="preserve"
id="flowRoot7566"
style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
transform="translate(474.85167,-275.12663)"><flowRegion
id="flowRegion7568"><rect
id="rect7570"
width="78.37838"
height="113.51351"
x="60.81081"
y="575.17554"
style="font-size:24px" /></flowRegion><flowPara
id="flowPara7572">c)</flowPara></flowRoot> <path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.95269799;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Sstart);marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 670.41494,504.68449 L 670.23212,469.62547 L 670.23212,469.62547 L 670.23212,469.62547 L 670.23212,469.62547"
id="path2552" />
<g
id="g4730"
transform="translate(162.10811,-110.37838)">
<flowRoot
transform="translate(-9.52871,93.700078)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
id="flowRoot4694"
xml:space="preserve"><flowRegion
id="flowRegion4696"><rect
style="fill:#000000;fill-opacity:1"
y="493.35226"
x="509.61661"
height="54.214523"
width="66.412804"
id="rect4698" /></flowRegion><flowPara
style="font-weight:bold"
id="flowPara4700">n</flowPara></flowRoot> <flowRoot
transform="translate(-74.09053,167.26565)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
id="flowRoot4702"
xml:space="preserve"><flowRegion
id="flowRegion4704"><rect
style="fill:#000000;fill-opacity:1"
y="444.55917"
x="608.55817"
height="28.462643"
width="29.818018"
id="rect4706" /></flowRegion><flowPara
style="font-size:20px;fill:#000000;fill-opacity:1"
id="flowPara4708">ij</flowPara></flowRoot> <flowRoot
transform="translate(-76.92541,135.39594)"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
id="flowRoot4710"
xml:space="preserve"><flowRegion
id="flowRegion4712"><rect
style="fill:#000000;fill-opacity:1"
y="444.55917"
x="608.55817"
height="28.462643"
width="29.818018"
id="rect4714" /></flowRegion><flowPara
style="font-size:20px;fill:#000000;fill-opacity:1"
id="flowPara4716">k</flowPara></flowRoot> </g>
<flowRoot
xml:space="preserve"
id="flowRoot2580"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
transform="translate(125.01676,-115.57119)"><flowRegion
id="flowRegion2582"><rect
id="rect2584"
width="83.980377"
height="54.214508"
x="509.61661"
y="493.35226"
style="fill:#0000ff;fill-opacity:1" /></flowRegion><flowPara
id="flowPara2586">b</flowPara></flowRoot> <flowRoot
xml:space="preserve"
id="flowRoot2588"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
transform="translate(68.45494,-40.00562)"><flowRegion
id="flowRegion2590"><rect
id="rect2592"
width="29.818018"
height="28.462643"
x="608.55817"
y="444.55917"
style="fill:#0000ff;fill-opacity:1" /></flowRegion><flowPara
id="flowPara2594"
style="font-size:20px;fill:#0000ff;fill-opacity:1">i</flowPara></flowRoot> <flowRoot
xml:space="preserve"
id="flowRoot2596"
style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
transform="translate(71.62006,-71.87533)"><flowRegion
id="flowRegion2598"><rect
id="rect2600"
width="29.818018"
height="28.462643"
x="608.55817"
y="444.55917"
style="fill:#0000ff;fill-opacity:1" /></flowRegion><flowPara
id="flowPara2602"
style="font-size:20px;fill:#0000ff;fill-opacity:1">k</flowPara></flowRoot> </g>
</svg>

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -0,0 +1,554 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="1035.3572"
height="581.78564"
id="svg2"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="car-propertynames.svg">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible">
<path
id="path3793"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<linearGradient
id="linearGradient3624">
<stop
style="stop-color:#ffccaa;stop-opacity:0;"
offset="0"
id="stop3626" />
<stop
style="stop-color:#ffccaa;stop-opacity:1;"
offset="1"
id="stop3628" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624"
id="radialGradient3630"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,77.93026,22.058642)"
gradientUnits="userSpaceOnUse" />
<inkscape:perspective
id="perspective3640"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-4"
id="radialGradient3630-0"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,77.93026,22.058642)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3624-4">
<stop
style="stop-color:#ffccaa;stop-opacity:0;"
offset="0"
id="stop3626-7" />
<stop
style="stop-color:#ffccaa;stop-opacity:1;"
offset="1"
id="stop3628-6" />
</linearGradient>
<inkscape:perspective
id="perspective3640-9"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-8"
id="radialGradient3630-06"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,77.93026,22.058642)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3624-8">
<stop
style="stop-color:#ffccaa;stop-opacity:0;"
offset="0"
id="stop3626-79" />
<stop
style="stop-color:#ffccaa;stop-opacity:1;"
offset="1"
id="stop3628-0" />
</linearGradient>
<inkscape:perspective
id="perspective3640-3"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3"
id="radialGradient3630-7"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,77.93026,22.058642)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3624-3">
<stop
style="stop-color:#ffccaa;stop-opacity:0;"
offset="0"
id="stop3626-2" />
<stop
style="stop-color:#ffccaa;stop-opacity:1;"
offset="1"
id="stop3628-65" />
</linearGradient>
<inkscape:perspective
id="perspective3640-5"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-7"
id="radialGradient3630-8"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,77.93026,22.058642)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3624-7">
<stop
style="stop-color:#ffccaa;stop-opacity:0;"
offset="0"
id="stop3626-9" />
<stop
style="stop-color:#ffccaa;stop-opacity:1;"
offset="1"
id="stop3628-60" />
</linearGradient>
<radialGradient
r="154.82143"
fy="-38.634254"
fx="117.96088"
cy="-38.634254"
cx="117.96088"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,401.50169,134.21685)"
gradientUnits="userSpaceOnUse"
id="radialGradient3649-4"
xlink:href="#linearGradient3624-7"
inkscape:collect="always" />
<inkscape:perspective
id="perspective3640-0"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-87"
id="radialGradient3630-4"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,77.93026,22.058642)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3624-87">
<stop
style="stop-color:#ffccaa;stop-opacity:0;"
offset="0"
id="stop3626-0" />
<stop
style="stop-color:#ffccaa;stop-opacity:1;"
offset="1"
id="stop3628-8" />
</linearGradient>
<radialGradient
r="154.82143"
fy="-38.634254"
fx="117.96088"
cy="-38.634254"
cx="117.96088"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,364.35883,551.34436)"
gradientUnits="userSpaceOnUse"
id="radialGradient3649-6"
xlink:href="#linearGradient3624-87"
inkscape:collect="always" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3"
id="radialGradient3777"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,-501.35545,-167.22707)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-4"
id="radialGradient3779"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,-85.641168,-148.65564)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-8"
id="radialGradient3783"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,332.93026,-141.51278)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<inkscape:perspective
id="perspective4243"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend-9"
style="overflow:visible">
<path
id="path3793-3"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<inkscape:perspective
id="perspective4271"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend-2"
style="overflow:visible">
<path
id="path3793-8"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<inkscape:perspective
id="perspective4299"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend-0"
style="overflow:visible">
<path
id="path3793-1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<inkscape:perspective
id="perspective4327"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend-8"
style="overflow:visible">
<path
id="path3793-9"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="116.87789"
inkscape:cy="598.80626"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1180"
inkscape:window-x="-3"
inkscape:window-y="-3"
inkscape:window-maximized="1">
<sodipodi:guide
orientation="0,1"
position="1216.25,580.53564"
id="guide3781" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(333.39286,111.74492)">
<g
id="g3766"
transform="translate(-771.42857,-160.96781)">
<rect
ry="24.285715"
y="223.09183"
x="439.28571"
height="61.42857"
width="307.14285"
id="rect2816-1"
style="color:#000000;fill:url(#radialGradient3649-4);fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text2830"
y="268.7182"
x="530.60126"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
y="268.7182"
x="530.60126"
id="tspan2832"
sodipodi:role="line">Sedan</tspan><tspan
id="tspan2834"
y="318.7182"
x="530.60126"
sodipodi:role="line" /></text>
</g>
<g
id="g3761"
transform="translate(-84.999983,123.80949)">
<rect
ry="24.285715"
y="110.93361"
x="115.71429"
height="61.42857"
width="307.14285"
id="rect2816"
style="color:#000000;fill:url(#radialGradient3630);fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text2836"
y="152.68304"
x="203.84625"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
y="152.68304"
x="203.84625"
id="tspan2838"
sodipodi:role="line">Pickup</tspan></text>
</g>
<g
id="g3772"
transform="translate(-8.5713543,-232.85715)">
<rect
ry="24.285715"
y="640.2193"
x="402.14285"
height="61.42857"
width="307.14285"
id="rect2816-2"
style="color:#000000;fill:url(#radialGradient3649-6);fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text2848"
y="685.23047"
x="434.20062"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
y="685.23047"
x="434.20062"
id="tspan2850"
sodipodi:role="line">Hummer H1</tspan></text>
</g>
<g
id="g3746"
transform="translate(131.42858,-32.142813)">
<rect
ry="24.285715"
y="-78.352104"
x="-463.57144"
height="61.42857"
width="307.14285"
id="rect2816-6"
style="color:#000000;fill:url(#radialGradient3777);fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text2818"
y="-36.954224"
x="-441.49414"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
id="tspan2824"
y="-36.954224"
x="-441.49414"
sodipodi:role="line">Compact Car</tspan></text>
</g>
<g
id="g3751"
transform="translate(78.571443,-50.714243)">
<rect
ry="24.285715"
y="-59.780674"
x="-47.85714"
height="61.42857"
width="307.14285"
id="rect2816-8"
style="color:#000000;fill:url(#radialGradient3779);fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text2840"
y="-14.15428"
x="52.999443"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
y="-14.15428"
x="52.999443"
id="tspan2842"
sodipodi:role="line">Truck</tspan></text>
</g>
<g
id="g3756"
transform="translate(22.857204,-57.8571)">
<rect
ry="24.285715"
y="-52.637817"
x="370.71429"
height="61.42857"
width="307.14285"
id="rect2816-3"
style="color:#000000;fill:url(#radialGradient3783);fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text2844"
y="-9.0663891"
x="472.85715"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
y="-9.0663891"
x="472.85715"
id="tspan2846"
sodipodi:role="line">Tank</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Lend)"
d="m -178.57144,-50.494961 0,107.856887"
id="path3785"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Lend)"
d="m 184.28573,-47.280549 0,276.428319"
id="path3785-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Lend)"
d="m 547.14292,-48.709121 0,450.174561"
id="path3785-9-3"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Lend)"
d="M -178.57144,124.65179 33.560595,236.54929"
id="path3785-7"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Lend)"
d="m 184.85791,297.38788 212.13203,111.8975"
id="path3785-7-1"
sodipodi:nodetypes="cc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,820 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="510.65839"
height="508.60782"
id="svg2"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="car-propertynames.svg">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible">
<path
id="path3793"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<linearGradient
id="linearGradient3624">
<stop
style="stop-color:#ffccaa;stop-opacity:0;"
offset="0"
id="stop3626" />
<stop
style="stop-color:#ffccaa;stop-opacity:1;"
offset="1"
id="stop3628" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<inkscape:perspective
id="perspective3640"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-4"
id="radialGradient3630-0"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,77.93026,22.058642)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3624-4">
<stop
style="stop-color:#ffccaa;stop-opacity:0;"
offset="0"
id="stop3626-7" />
<stop
style="stop-color:#ffccaa;stop-opacity:1;"
offset="1"
id="stop3628-6" />
</linearGradient>
<inkscape:perspective
id="perspective3640-9"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-8"
id="radialGradient3630-06"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,77.93026,22.058642)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3624-8">
<stop
style="stop-color:#ffccaa;stop-opacity:0;"
offset="0"
id="stop3626-79" />
<stop
style="stop-color:#ffccaa;stop-opacity:1;"
offset="1"
id="stop3628-0" />
</linearGradient>
<inkscape:perspective
id="perspective3640-3"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3"
id="radialGradient3630-7"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,77.93026,22.058642)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3624-3">
<stop
style="stop-color:#aaccff;stop-opacity:0;"
offset="0"
id="stop3626-2" />
<stop
style="stop-color:#abaaff;stop-opacity:1;"
offset="1"
id="stop3628-65" />
</linearGradient>
<inkscape:perspective
id="perspective3640-5"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-7"
id="radialGradient3630-8"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,77.93026,22.058642)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3624-7">
<stop
style="stop-color:#ffccaa;stop-opacity:0;"
offset="0"
id="stop3626-9" />
<stop
style="stop-color:#ffccaa;stop-opacity:1;"
offset="1"
id="stop3628-60" />
</linearGradient>
<inkscape:perspective
id="perspective3640-0"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-87"
id="radialGradient3630-4"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,77.93026,22.058642)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3624-87">
<stop
style="stop-color:#ffccaa;stop-opacity:0;"
offset="0"
id="stop3626-0" />
<stop
style="stop-color:#ffccaa;stop-opacity:1;"
offset="1"
id="stop3628-8" />
</linearGradient>
<inkscape:perspective
id="perspective4243"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend-9"
style="overflow:visible">
<path
id="path3793-3"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<inkscape:perspective
id="perspective4271"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend-2"
style="overflow:visible">
<path
id="path3793-8"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<inkscape:perspective
id="perspective4299"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend-0"
style="overflow:visible">
<path
id="path3793-1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<inkscape:perspective
id="perspective4327"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend-8"
style="overflow:visible">
<path
id="path3793-9"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3"
id="radialGradient4540"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,-369.92687,-199.36988)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<inkscape:perspective
id="perspective4682"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7"
id="radialGradient4540-9"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,-369.92687,-199.36988)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<linearGradient
id="linearGradient3624-3-7">
<stop
style="stop-color:#aaccff;stop-opacity:0;"
offset="0"
id="stop3626-2-8" />
<stop
style="stop-color:#abaaff;stop-opacity:1;"
offset="1"
id="stop3628-65-2" />
</linearGradient>
<radialGradient
r="154.82143"
fy="-38.634254"
fx="117.96088"
cy="-38.634254"
cx="117.96088"
gradientTransform="matrix(0.22383877,0.73556295,-0.66939186,0.20370232,-297.23817,-95.263514)"
gradientUnits="userSpaceOnUse"
id="radialGradient4693"
xlink:href="#linearGradient3624-3-7"
inkscape:collect="always" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7"
id="radialGradient4723"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.22383877,0.73556295,-0.66939186,0.20370232,-297.23817,-95.263514)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<inkscape:perspective
id="perspective4738"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7-0"
id="radialGradient4723-9"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.22383877,0.73556295,-0.66939186,0.20370232,-297.23817,-95.263514)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<linearGradient
id="linearGradient3624-3-7-0">
<stop
style="stop-color:#aaccff;stop-opacity:0;"
offset="0"
id="stop3626-2-8-2" />
<stop
style="stop-color:#abaaff;stop-opacity:1;"
offset="1"
id="stop3628-65-2-0" />
</linearGradient>
<inkscape:perspective
id="perspective4738-1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7-07"
id="radialGradient4723-2"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.22383877,0.73556295,-0.66939186,0.20370232,-297.23817,-95.263514)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<linearGradient
id="linearGradient3624-3-7-07">
<stop
style="stop-color:#aaccff;stop-opacity:0;"
offset="0"
id="stop3626-2-8-3" />
<stop
style="stop-color:#abaaff;stop-opacity:1;"
offset="1"
id="stop3628-65-2-1" />
</linearGradient>
<inkscape:perspective
id="perspective4738-7"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7-4"
id="radialGradient4723-7"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.22383877,0.73556295,-0.66939186,0.20370232,-297.23817,-95.263514)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<linearGradient
id="linearGradient3624-3-7-4">
<stop
style="stop-color:#aaccff;stop-opacity:0;"
offset="0"
id="stop3626-2-8-0" />
<stop
style="stop-color:#abaaff;stop-opacity:1;"
offset="1"
id="stop3628-65-2-6" />
</linearGradient>
<inkscape:perspective
id="perspective4738-5"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7-2"
id="radialGradient4723-8"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.22383877,0.73556295,-0.66939186,0.20370232,-297.23817,-95.263514)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<linearGradient
id="linearGradient3624-3-7-2">
<stop
style="stop-color:#aaccff;stop-opacity:0;"
offset="0"
id="stop3626-2-8-6" />
<stop
style="stop-color:#abaaff;stop-opacity:1;"
offset="1"
id="stop3628-65-2-06" />
</linearGradient>
<inkscape:perspective
id="perspective4738-6"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7-7"
id="radialGradient4723-0"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.22383877,0.73556295,-0.66939186,0.20370232,-297.23817,-95.263514)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<linearGradient
id="linearGradient3624-3-7-7">
<stop
style="stop-color:#aaccff;stop-opacity:0;"
offset="0"
id="stop3626-2-8-01" />
<stop
style="stop-color:#abaaff;stop-opacity:1;"
offset="1"
id="stop3628-65-2-01" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3"
id="radialGradient4865"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.22529395,0.74034487,-0.6737436,0.2050266,-369.92687,-199.36988)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3"
id="radialGradient4870"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.37222048,0.73916728,-1.1131288,0.20470048,-394.48823,-198.87502)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7"
id="radialGradient4875"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.36981629,0.73439296,-1.105939,0.20337831,-394.09834,-121.57274)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7-0"
id="radialGradient4880"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.36981629,0.73439296,-1.105939,0.20337831,-394.09834,-45.041711)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7-07"
id="radialGradient4885"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.36981629,0.73439296,-1.105939,0.20337831,-394.09834,31.489319)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7-4"
id="radialGradient4890"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.36981629,0.73439296,-1.105939,0.20337831,-394.09834,108.02036)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7-2"
id="radialGradient4895"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.36981629,0.73439296,-1.105939,0.20337831,-394.09834,184.55139)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7-7"
id="radialGradient4900"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.22383877,0.73556295,-0.66939186,0.20370232,-369.96915,261.32034)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7-2"
id="radialGradient4932"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.36981629,0.73439296,-1.105939,0.20337831,-394.09834,184.55139)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3"
id="radialGradient4934"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.37222048,0.73916728,-1.1131288,0.20470048,-394.48823,-198.87502)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7-4"
id="radialGradient4936"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.36981629,0.73439296,-1.105939,0.20337831,-394.09834,108.02036)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7-07"
id="radialGradient4938"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.36981629,0.73439296,-1.105939,0.20337831,-394.09834,31.489319)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7-0"
id="radialGradient4940"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.36981629,0.73439296,-1.105939,0.20337831,-394.09834,-45.041711)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3624-3-7"
id="radialGradient4942"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.36981629,0.73439296,-1.105939,0.20337831,-394.09834,-121.57274)"
cx="117.96088"
cy="-38.634254"
fx="117.96088"
fy="-38.634254"
r="154.82143" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="480.81912"
inkscape:cy="235.68721"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1180"
inkscape:window-x="-3"
inkscape:window-y="-3"
inkscape:window-maximized="1">
<sodipodi:guide
orientation="0,1"
position="1216.5287,507.35588"
id="guide3781" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(333.67159,111.74684)">
<g
id="g4927"
transform="translate(-0.00299716,0)">
<rect
ry="0"
y="-110.14142"
x="-332.06317"
height="61.33086"
width="507.44754"
id="rect2816-6"
style="color:#000000;fill:url(#radialGradient4934);fill-opacity:1;stroke:#000000;stroke-width:3.21084785;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text2818"
y="-69.097038"
x="-310.34381"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
id="tspan2824"
y="-69.097038"
x="-310.34381"
sodipodi:role="line">GasUsage</tspan></text>
</g>
<g
id="g4922"
transform="translate(0,12.323853)">
<rect
ry="0"
y="-33.412281"
x="-332.07654"
height="60.934723"
width="504.16992"
id="rect2816-6-5"
style="color:#000000;fill:url(#radialGradient4942);fill-opacity:1;stroke:#000000;stroke-width:3.19010878;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text2818-3"
y="7.5559573"
x="-311.34378"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
id="tspan2824-4"
y="7.5559573"
x="-311.34378"
sodipodi:role="line">TopSpeed</tspan></text>
</g>
<g
id="g4917"
transform="translate(0,24.647736)">
<rect
ry="0"
y="43.118752"
x="-332.07654"
height="60.934723"
width="504.16992"
id="rect2816-6-5-9"
style="color:#000000;fill:url(#radialGradient4940);fill-opacity:1;stroke:#000000;stroke-width:3.19010878;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text2818-3-6"
y="84.208916"
x="-311.34378"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
id="tspan2824-4-2"
y="84.208916"
x="-311.34378"
sodipodi:role="line">NumSeats</tspan></text>
</g>
<g
id="g4912"
transform="translate(0,36.971619)">
<rect
ry="0"
y="119.64978"
x="-332.07654"
height="60.934723"
width="504.16992"
id="rect2816-6-5-0"
style="color:#000000;fill:url(#radialGradient4938);fill-opacity:1;stroke:#000000;stroke-width:3.19010878;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text2818-3-5"
y="160.86186"
x="-311.34378"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
id="tspan2824-4-6"
y="160.86186"
x="-311.34378"
sodipodi:role="line">AutomaticTransmission</tspan></text>
</g>
<g
id="g4907"
transform="translate(0,49.295471)">
<rect
ry="0"
y="196.18082"
x="-332.07654"
height="60.934723"
width="504.16992"
id="rect2816-6-5-7"
style="color:#000000;fill:url(#radialGradient4936);fill-opacity:1;stroke:#000000;stroke-width:3.19010878;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text2818-3-4"
y="237.51483"
x="-311.34378"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
id="tspan2824-4-8"
y="237.51483"
x="-311.34378"
sodipodi:role="line">CannonCalibre</tspan></text>
</g>
<g
id="g4902"
transform="translate(0,61.619305)">
<rect
ry="0"
y="272.71188"
x="-332.07654"
height="60.934723"
width="504.16992"
id="rect2816-6-5-4"
style="color:#000000;fill:url(#radialGradient4932);fill-opacity:1;stroke:#000000;stroke-width:3.19010878;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text2818-3-62"
y="314.16779"
x="-311.34378"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
id="tspan2824-4-89"
y="314.16779"
x="-311.34378"
sodipodi:role="line">Payload</tspan></text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -0,0 +1,44 @@
#FIG 3.2 Produced by xfig version 3.2.5
Landscape
Center
Metric
A4
100.00
Single
-2
1200 2
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
3015 3870 8775 3870 8775 6615 3015 6615 3015 3870
2 2 0 1 0 31 50 -1 20 0.000 0 0 -1 0 0 5
4095 4770 7650 4770 7650 5760 4095 5760 4095 4770
2 2 2 1 0 7 50 -1 41 3.000 0 0 -1 0 0 5
3015 6615 8775 6615 8775 6795 3015 6795 3015 6615
2 2 2 1 0 7 50 -1 41 3.000 0 0 -1 0 0 5
3015 3690 8775 3690 8775 3870 3015 3870 3015 3690
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
0 0 1.00 105.00 120.00
9000 4410 9450 4410
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
0 0 1.00 105.00 120.00
9000 4815 9450 4815
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
0 0 1.00 105.00 120.00
9000 5220 9450 5220
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
0 0 1.00 105.00 120.00
9045 5670 9450 5670
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
0 0 1.00 105.00 120.00
9045 6075 9450 6075
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
0 0 1.00 105.00 120.00
9045 6480 9450 6480
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
0 0 1.00 105.00 120.00
9000 4005 9450 4005
4 0 0 50 -1 0 12 0.0000 4 135 615 5535 7245 no flow\001
4 0 0 50 -1 0 12 0.0000 4 135 615 5535 3420 no flow\001
4 0 0 50 -1 0 12 0.0000 4 135 240 9720 4995 qw\001
4 0 0 50 -1 0 12 0.0000 4 135 210 9765 5490 qo\001
4 0 0 50 -1 0 12 0.0000 4 135 240 1170 4815 pw\001
4 0 0 50 -1 0 12 0.0000 4 135 105 1170 5310 S\001

View File

@ -0,0 +1,77 @@
#FIG 3.2 Produced by xfig version 3.2.5
Landscape
Center
Metric
A4
100.00
Single
-2
1200 2
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
3015 3870 8775 3870 8775 6615 3015 6615 3015 3870
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
2610 3870 2610 4950
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
2610 5535 2610 6615
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
6435 3690 8775 3690
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
4860 5805 4860 6075
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
4860 6390 4860 6615
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3870 4770 3870 5085
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3870 5445 3870 5760
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3915 4770 3780 4770
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3915 5760 3780 5760
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3015 3690 5355 3690
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
4140 4590 5580 4590
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
6390 4590 7650 4590
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
8550 5220 8775 5220
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
7695 5220 7920 5220
2 2 0 1 0 31 50 -1 20 0.000 0 0 -1 0 0 5
4095 4770 7650 4770 7650 5760 4095 5760 4095 4770
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
3 1 3.00 60.00 120.00
7965 6840 5985 5355
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
3 1 3.00 60.00 120.00
5380 6827 6167 6258
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
2700 3870 2565 3870
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
2700 6615 2565 6615
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3015 3780 3015 3600
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
8775 3780 8775 3600
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
7650 4680 7650 4500
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
4095 4680 4095 4500
2 2 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 5
6615 6840 9900 6840 9900 8055 6615 8055 6615 6840
2 2 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 5
2835 6840 6075 6840 6075 8055 2835 8055 2835 6840
4 0 0 50 -1 0 12 0.0000 4 135 330 7965 5265 L3x\001
4 0 0 50 -1 0 12 0.0000 4 135 330 5670 4635 L2x\001
4 0 0 50 -1 0 12 0.0000 4 135 330 5445 3780 L1x\001
4 0 0 50 -1 0 12 0.0000 4 180 345 4455 6300 H2y\001
4 0 0 50 -1 0 12 0.0000 4 180 345 3330 5310 H3y\001
4 0 0 50 -1 0 12 0.0000 4 180 345 2115 5310 H1y\001
4 0 0 50 -1 0 12 0.0000 4 135 285 2970 7695 Lin\001
4 0 0 50 -1 0 12 0.0000 4 180 375 2970 7425 phi1\001
4 0 0 50 -1 0 12 0.0000 4 135 240 2970 7155 K1\001
4 0 0 50 -1 0 12 0.0000 4 135 240 6750 7155 K2\001
4 0 0 50 -1 0 12 0.0000 4 180 375 6750 7380 phi2\001
4 0 0 50 -1 0 12 0.0000 4 135 375 6750 7650 BC1\001
4 0 0 50 -1 0 12 0.0000 4 135 375 6750 7920 BC2\001
4 0 0 50 -1 0 12 0.0000 4 135 390 2970 7920 Lin2\001

View File

@ -0,0 +1,37 @@
#FIG 3.2 Produced by xfig version 3.2.5
Landscape
Center
Metric
A4
100.00
Single
-2
1200 2
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3285 5310 3285 5535
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3285 5445 4905 5445
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
5715 5445 7155 5445
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
7155 5310 7155 5535
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3060 4725 3060 5040
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
2970 5130 3150 5130
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3060 4680 3060 5130
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
3240 3870 7155 3870 7155 5130 3240 5130 3240 3870
2 2 0 1 0 15 50 -1 20 0.000 0 0 -1 0 0 5
5265 3870 7155 3870 7155 5130 5265 5130 5265 3870
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3060 3870 3060 4320
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
2970 3870 3150 3870
4 0 0 50 -1 0 12 0.0000 4 135 390 3870 4365 K1 =\001
4 0 0 50 -1 0 12 0.0000 4 180 525 3870 4590 phi1 =\001
4 0 7 50 -1 0 12 0.0000 4 135 390 5760 4365 K2 =\001
4 0 7 50 -1 0 12 0.0000 4 180 525 5760 4545 phi2 =\001
4 0 0 50 -1 0 12 0.0000 4 135 510 2700 4590 300 m\001
4 0 0 50 -1 0 12 0.0000 4 135 510 5085 5490 600 m\001

View File

@ -0,0 +1,31 @@
#FIG 3.2 Produced by xfig version 3.2.5
Landscape
Center
Metric
A4
100.00
Single
-2
1200 2
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
1980 2205 3780 2205 3780 3915 1980 3915 1980 2205
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
1890 3915 1755 3915
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
1800 3915 1800 3240
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
1800 2880 1800 2205
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
1845 2205 1710 2205
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
1845 3915 1710 3915
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3195 4095 3780 4095
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3780 4005 3780 4140
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
1980 4005 1980 4140
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
1980 4095 2565 4095
4 0 0 50 -1 0 12 0.0000 4 135 105 1575 3105 y\001
4 0 0 50 -1 0 12 0.0000 4 90 105 2655 4140 x\001

120
doc/handbook/box.tex Normal file
View File

@ -0,0 +1,120 @@
\section{Box method - A short introduction}\label{box}
For the spatial discretization the so called BOX-method is used which unites the advantages of the finite-volume (FV) and finite-element (FE) methods.
First, the model domain $G$ is discretized with a FE mesh consisting of nodes i and corresponding elements $E_k$. Then, a secondary FV mesh is constructed by connecting the midpoints and barycenters of the elements surrounding node i creating a box $B_i$ around node i (see Figure \ref{pc:box}a).
\begin{figure} [h]
\includegraphics[width=0.8\linewidth,keepaspectratio]{EPS/box_disc}
\caption{\label{pc:box} Discretization of the BOX-method}
\end{figure}
The FE mesh divides the box $B_i$ into subcontrolvolumes (scv's) $b^k_i$ (see Figure \ref{pc:box}b). Figure \ref{pc:box}c shows the finite element $E_k$ and the scv's $b^k_i$ inside $E_k$, which belong to four different boxes $B_i$. Also necessary for the discretization are the faces of the subcontrolvolumes (scvf's) $e^k_{ij}$ between the scv's $b^k_i$ and $b^k_j$, where $|e^k_{ij}|$ is the length of the scvf. The integration points $x^k_{ij}$ on $e^k_{ij}$ and the outer normal vector $\mathbf n^k_{ij}$ are also to be defined (see Figure \ref{pc:box}c).
The advantage of the FE method is that unstructured grids can be used, while the FV method is mass conservative. The idea is to apply the FV method (balance of fluxes across the interfaces) to each FV box $B_i$ and to get the fluxes across the interfaces $e^k_{ij}$ at the integration points $x^k_{ij}$ from the FE approach. Consequently, at each scvf the following expression results:
\begin{equation}
f(\tilde u(x^k_{ij})) \cdot \mathbf n^k_{ij} \: |e^k_{ij}| \qquad \textrm{with} \qquad \tilde u(x^k_{ij}) = \sum_i N_i(x^k_{ij}) \cdot \hat u_i .
\end{equation}
In the following, the discretization of the balance equation is going to be derived. From the \textsc{Reynolds} transport theorem follows the general balance equation:
\begin{equation}
\underbrace{\int_G \frac{\partial}{\partial t} \: u \: dG}_{1} + \underbrace{\int_{\partial G} (\mathbf{v} u + \mathbf w) \cdot \textbf n \: d\varGamma}_{2} = \underbrace{\int_G q \: dG}_{3}
\end{equation}
\begin{equation}
f(u) = \int_G \frac{\partial u}{\partial t} \: dG + \int_{G} \nabla \cdot \underbrace{\left[ \mathbf{v} u + \mathbf w(u)\right] }_{F(u)} \: dG - \int_G q \: dG = 0
\end{equation}
where term 1 describes the changes of entity $u$ within a control volume over time, term 2 the advective, diffusive and dispersive fluxes over the interfaces of the control volume and term 3 is the source and sink term. $G$ denotes the model domain and $F(u) = F(\mathbf v, p) = F(\mathbf v(x,t), p(x,t))$.
Like the FE method, the BOX-method follows the principle of weighted residuals. In the function $f(u)$ the unknown $u$ is approximated by discrete values at the nodes of the FE mesh $\hat u_i$ and linear basis functions $N_i$ yielding an approximate function $f(\tilde u)$. For $u\in \lbrace \mathbf v, p, x^\kappa \rbrace$ this means
\begin{minipage}[b]{0.47\textwidth}
\begin{equation}
\label{eq:p}
\tilde p = \sum_i N_i \hat{p_i}
\end{equation}
\begin{equation}
\label{eq:v}
\tilde{\mathbf v} = \sum_i N_i \hat{\mathbf v}
\end{equation}
\begin{equation}
\label{eq:x}
\tilde x^\kappa = \sum_i N_i \hat x^\kappa
\end{equation}
\end{minipage}
\hfill
\begin{minipage}[b]{0.47\textwidth}
\begin{equation}
\label{eq:dp}
\nabla \tilde p = \sum_i \nabla N_i \hat{p_i}
\end{equation}
\begin{equation}
\label{eq:dv}
\nabla \tilde{\mathbf v} = \sum_i \nabla N_i \hat{\mathbf v}
\end{equation}
\begin{equation}
\label{eq:dx}
\nabla \tilde x^\kappa = \sum_i \nabla N_i \hat x^\kappa .
\end{equation}
\end{minipage}
Due to the approximation with node values and basis functions the differential equations are not exactly fulfilled anymore but a residual $\varepsilon$ is produced.
\begin{equation}
f(u) = 0 \qquad \Rightarrow \qquad f(\tilde u) = \varepsilon
\end{equation}
Application of the principle of weighted residuals, meaning the multiplication of the residual $\varepsilon$ with a weighting function $W_j$ and claiming that this product has to vanish within the whole domain,
\begin{equation}
\int_G W_j \cdot \varepsilon \: \overset {!}{=} \: 0 \qquad \textrm{with} \qquad \sum_j W_j =1
\end{equation}
yields the following equation:
\begin{equation}
\int_G W_j \frac{\partial \tilde u}{\partial t} \: dG + \int_G W_j \cdot \left[ \nabla \cdot F(\tilde u) \right] \: dG - \int_G W_j \cdot q \: dG = \int_G W_j \cdot \varepsilon \: dG \: \overset {!}{=} \: 0 .
\end{equation}
Then, the chain rule and the \textsc{Green-Gaussian} integral theorem are applied.
\begin{equation}
\int_G W_j \frac{\partial \sum_i N_i \hat u_i}{\partial t} \: dG + \int_{\partial G} \left[ W_j \cdot F(\tilde u)\right] \cdot \mathbf n \: d\varGamma_G + \int_G \nabla W_j \cdot F(\tilde u) \: dG - \int_G W_j \cdot q \: dG = 0
\end{equation}
A mass lumping technique is applied by assuming that the storage capacity is reduced to the nodes. This means that the integrals $M_{i,j} = \int_G W_j \: N_i \: dG$ are replaced by the mass lumping term $M^{lump}_{i,j}$ which is defined as:
\begin{equation}
M^{lump}_{i,j} =\begin{cases} \int_G W_j \: dG = \int_G N_i \: dG = V_i &i = j\\
0 &i \neq j\\
\end{cases}
\end{equation}
where $V_i$ is the volume of the FV box $B_i$ associated with node i. The application of this assumption in combination with $\int_G W_j \:q \: dG = V_i \: q$ yields
\begin{equation}
V_i \frac{\partial \hat u_i}{\partial t} + \int_{\partial G} \left[ W_j \cdot F(\tilde u)\right] \cdot \mathbf n \: d\varGamma_G + \int_G \nabla W_j \cdot F(\tilde u) \: dG- V_i \cdot q = 0 \, .
\end{equation}
Defining the weighting function $W_j$ to be piecewisely constant over a control volume box $B_i$
\begin{equation}
W_j(x) = \begin{cases}
1 &x \in B_i \\
0 &x \notin B_i\\
\end{cases}
\end{equation}
causes $\nabla W_j = 0$:
\begin{equation}
\label{eq:disc1}
V_i \frac{\partial \hat u_i}{\partial t} + \int_{\partial B_i} \left[ W_j \cdot F(\tilde u)\right] \cdot \mathbf n \; d{\varGamma}_{B_i} - V_i \cdot q = 0 .
\end{equation}
The consideration of the time discretization and inserting $W_j = 1$ finally lead to the discretized form which will be applied to the mathematical flow and transport equations:
\begin{equation}
\label{eq:discfin}
V_i \frac{\hat u_i^{n+1} - \hat u_i^{n}}{\Delta t} + \int_{\partial B_i} F(\tilde u^{n+1}) \cdot \mathbf n \; d{\varGamma}_{B_i} - V_i \: q^{n+1} \: = 0
\end{equation}

11
doc/handbook/build-handbook.sh Executable file
View File

@ -0,0 +1,11 @@
#! /bin/sh
# this script builds the eWoms handbook from its LaTeX sources. The
# result file is called "ewoms-handbook.pdf"
latex ewoms-handbook || exit $?
bibtex ewoms-handbook || exit $?
latex ewoms-handbook || exit $?
latex ewoms-handbook || exit $?
dvipdf ewoms-handbook || exit $?
rm ewoms-handbook.dvi

View File

@ -0,0 +1,475 @@
\chapter{Design Patterns}
\label{chap:DesignPatterns}
This chapter tries to give a high-level understanding of some of the
fundamental techniques which are used by \Dune and \eWoms and the
motivation behind these design decisions. It is assumed that the
reader already has basic experience in object oriented programming
with \Cplusplus.
First, a quick motivation of \Cplusplus template programming is given. Then
follows an introduction to polymorphism and its opportunities as
opened by the template mechanism. After that, some drawbacks
associated with template programming are discussed, in particular the
blow-up of identifier names, the proliferation of template arguments
and some approaches on how to deal with these problems.
\section{\Cplusplus Template Programming}
One of the main features of modern versions of the \Cplusplus programming
language is robust support for templates. Templates are a mechanism
for code generation built directly into the compiler. For the
motivation behind templates, consider a linked list of \texttt{double}
values which could be implemented like this:
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize,numbers=left,numberstyle=\tiny, numbersep=5pt]
struct DoubleList {
DoubleList(const double &val, DoubleList *prevNode = 0)
{ value = val; if (prevNode) prevNode->next = this; };
double value;
DoubleList *next;
};
int main() {
DoubleList *head, *tail;
head = tail = new DoubleList(1.23);
tail = new DoubleList(2.34, tail);
tail = new DoubleList(3.56, tail);
};
\end{lstlisting}
But what should be done if a list of strings is also required? The
only ``clean'' way to achive this without templates would be to copy
\texttt{DoubleList}, then rename it and change the type of the
\texttt{value} attribute. It is obvious that this is a very
cumbersome, error-prone and unproductive process. For this reason,
recent standards of the \Cplusplus programming language specify the template
mechanism, which is a way of letting the compiler do the tedious work. Using
templates, a generic linked list can be implemented like this:
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize,numbers=left,numberstyle=\tiny, numbersep=5pt]
template <class ValueType>
struct List {
List(const ValueType &val, List *prevNode = 0)
{ value = val; if (prevNode) prevNode->next = this; };
ValueType value;
List *next;
};
int main() {
typedef List<double> DoubleList;
DoubleList *head, *tail;
head = tail = new DoubleList(1.23);
tail = new DoubleList(2.34, tail);
tail = new DoubleList(3.56, tail);
typedef List<const char*> StringList;
StringList *head2, *tail2;
head2 = tail2 = new StringList("Hello");
tail2 = new StringList(", ", tail2);
tail2 = new StringList("World!", tail2);
};
\end{lstlisting}
Compared to approaches which use external tools for code generation --
which is the approach chosen for example by the
FEniCS~\cite{FENICS-HP} project -- or heavy (ab)use of the C
preprocessor -- as done for example by the UG framework~\cite{UG-HP}
-- templates have several advantages:
\begin{description}
\item[Well Programmable:] Programming errors are directly detected by
the \Cplusplus compiler. Thus, diagnostic messages from the compiler are
directly useful because the source code compiled is the
same as the one written by the developer. This is not the case
for code generators and C-preprocessor macros where the actual
statements processed by the compiler are obfuscated.
\item[Easily Debugable:] Programs which use the template mechanism can be
debugged almost as easily as \Cplusplus programs which do not use
templates. This is due to the fact that the debugger always knows
the ``real'' source file and line number.
\end{description}
For these reasons \Dune and \eWoms extensively use the template
mechanism. Both projects also try to avoid duplicating functionality
provided by the Standard Template Library (STL,~\cite{STL-REF-HP})
which is part of the \Cplusplus-2003 standard and was further extended
in the \Cplusplus11 standard.
\section{Polymorphism}
In object oriented programming, some methods often make sense for all
classes in a hierarchy, but what actually needs to be \emph{done}
can differ for each concrete class. This observation motivates
\emph{polymorphism}. Fundamentally, polymorphism means all
techniques in which a method call results in the processor executing code
which is specific to the type of object for which the method is
called\footnote{This is the \emph{poly} of polymorphism: There are
multiple ways to achieve the same goal.}.
In \Cplusplus, there are two common ways to achieve polymorphism: The
traditional dynamic polymorphism which does not require template
programming, and static polymorphism which is made possible by the
template mechanism.
\subsection*{Dynamic Polymorphism}
To utilize \emph{dynamic polymorphism} in \Cplusplus, the polymorphic
methods are marked with the \texttt{virtual} keyword in the base
class. Internally, the compiler realizes dynamic polymorphism by
storing a pointer to a so-called \texttt{vtable} within each object of
polymorphic classes. The \texttt{vtable} itself stores the entry point
of each method which is declared \texttt{virtual}. If such a method is
called on an object, the compiler generates code which retrieves the
method's memory address from the object's \texttt{vtable} and then
continues execution at this address. This explains why this mechanism
is called \textbf{dynamic} polymorphism: the code which is actually
executed is dynamically determined at run time.
\begin{example}
\label{example:DynPoly}
A class called \texttt{Car} may feature the methods
\texttt{gasUsage} (on line \ref{designpatterns:virtual-usage}, which
by default roughly corresponds to the current $CO_2$ emission goal
of the European Union, but can be changed by classes representing
actual cars. Also, a method called \texttt{fuelTankSize} makes
sense for all cars, but since there is no useful default, its
\texttt{vtable} entry is set to $0$ in the base class on line
\ref{designpatterns:totally-virtual}. This tells the compiler that
it is mandatory for this method to be defined in derived
classes. Finally, the method \texttt{range} may calculate the
expected remaining kilometers the car can drive given a fill level
of the fuel tank. Since the \texttt{range} method can retrieve the
information it needs, it does not need to be polymorphic.
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize,numbers=left,numberstyle=\tiny, numbersep=5pt]
// The base class
class Car
{public:
virtual double gasUsage()
{ return 4.5; };/*@\label{designpatterns:virtual-usage}@*/
virtual double fuelTankSize() = 0;/*@\label{designpatterns:totally-virtual}@*/
double range(double fuelTankFillLevel)
{ return 100*fuelTankFillLevel*fuelTankSize()/gasUsage(); }
};
\end{lstlisting}
\noindent
Actual car models can now be derived from the base class like this:
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize,numbers=left,numberstyle=\tiny, numbersep=5pt]
// A Mercedes S-class car
class S : public Car
{public:
virtual double gasUsage() { return 9.0; };
virtual double fuelTankSize() { return 65.0; };
};
// A VW Lupo
class Lupo : public Car
{public:
virtual double gasUsage() { return 2.99; };
virtual double fuelTankSize() { return 30.0; };
};
\end{lstlisting}
\noindent
Calling the \texttt{range} method yields the correct result for any
kind of car:
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize,numbers=left,numberstyle=\tiny, numbersep=5pt]
void printMaxRange(Car &car)
{ std::cout << "Maximum Range: " << car.range(1.00) << "\n"; }
int main()
{
Lupo lupo;
S s;
std::cout << "VW Lupo:";
std::cout << "Median range: " << lupo.range(0.50) << "\n";
printMaxRange(lupo);
std::cout << "Mercedes S-Class:";
std::cout << "Median range: " << s.range(0.50) << "\n";
printMaxRange(s);
}
\end{lstlisting}
For both types of cars, \texttt{Lupo} and \texttt{S} the function
\texttt{printMaxRange} works as expected, it yields
$1003.3\;\mathrm{km}$ for the Lupo and $722.2\;\mathrm{km}$ for the
S-Class.
\end{example}
\begin{exc}
What happens if \dots
\begin{itemize}
\item \dots the \texttt{gasUsage} method is removed from the \texttt{Lupo} class?
\item \dots the \texttt{virtual} qualifier is removed in front of the
\texttt{gasUsage} method in the base class?
\item \dots the \texttt{fuelTankSize} method is removed from the \texttt{Lupo} class?
\item \dots the \texttt{range} method in the \texttt{S} class is
overwritten?
\end{itemize}
\end{exc}
\subsection*{Static Polymorphism}
Dynamic polymorphism has a few disadvantages. The most relevant in the
context of \eWoms is that the compiler can not see ``inside'' the
called methods and thus cannot optimize properly. For example, modern
\Cplusplus compilers 'inline' short methods, i.e. they copy the method's body
to where it is called. First, inlining allows to save a few
instructions by avoiding to jump into and out of the method. Second,
and more importantly, inlining also allows further optimizations which
depend on specific properties of the function arguments (e.g. constant
value elimination) or the contents of the function body (e.g. loop
unrolling). Unfortunately, inlining and other cross-method
optimizations are made next to impossible by dynamic
polymorphism. This is because these optimizations are accomplished by the
compiler (i.e. at compile time) whilst the code which actually gets
executed is only determined at run time for \texttt{virtual}
methods. To overcome this issue, template programming can be used to
achive polymorphism at compile time. This works by supplying the type
of the derived class as an additional template parameter to the base
class. Whenever the base class needs to call back the derived class, the \texttt{this} pointer of the base class is reinterpreted as
being a pointer to an object of the derived class and the method is
then called on the reinterpreted pointer. This scheme gives the \Cplusplus
compiler complete transparency of the code executed and thus opens
much better optimization oportunities. Since this mechanism completely
happens at compile time, it is called ``static polymorphism'' because
the called method cannot be dynamically changed at runtime.
\begin{example}
Using static polymorphism, the base class of example \ref{example:DynPoly}
can be implemented like this:
\begin{lstlisting}[name=staticcars,basicstyle=\ttfamily\scriptsize,numbers=left,numberstyle=\tiny, numbersep=5pt]
// The base class. The 'Imp' template parameter is the
// type of implementation, i.e. the derived class
template <class Imp>
class Car
{public:
double gasUsage()
{ return 4.5; };
double fuelTankSize()
{ throw "The derived class needs to implement the fuelTankSize() method"; };
double range(double fuelTankFillLevel)
{ return 100*fuelTankFillLevel*asImp_().fuelTankSize()/asImp_().gasUsage(); }
protected:
// reinterpret 'this' as a pointer to an object of type 'Imp'
Imp &asImp_() { return *static_cast<Imp*>(this); }
};
\end{lstlisting}
(Notice the \texttt{asImp\_()} calls in the \texttt{range} method.) The
derived classes may now be defined like this:
\begin{lstlisting}[name=staticcars,basicstyle=\ttfamily\scriptsize,numbers=left,numberstyle=\tiny, numbersep=5pt]
// A Mercedes S-class car
class S : public Car<S>
{public:
double gasUsage() { return 9.0; };
double fuelTankSize() { return 65.0; };
};
// A VW Lupo
class Lupo : public Car<Lupo>
{public:
double gasUsage() { return 2.99; };
double fuelTankSize() { return 30.0; };
};
\end{lstlisting}
\end{example}
\noindent
Analogous to example \ref{example:DynPoly}, the two kinds of cars can
be used generically within (template) functions:
\begin{lstlisting}[name=staticcars,basicstyle=\ttfamily\scriptsize,numbers=left,numberstyle=\tiny, numbersep=5pt]
template <class CarType>
void printMaxRange(CarType &car)
{ std::cout << "Maximum Range: " << car.range(1.00) << "\n"; }
int main()
{
Lupo lupo;
S s;
std::cout << "VW Lupo:";
std::cout << "Median range: " << lupo.range(0.50) << "\n";
printMaxRange(lupo);
std::cout << "Mercedes S-Class:";
std::cout << "Median range: " << s.range(0.50) << "\n";
printMaxRange(s);
return 0;
}
\end{lstlisting}
%\textbf{TODO: Exercise}
\section{Common Template Programming Related Problems}
Although \Cplusplus template programming opens a few intriguing
possibilities, it also has a few disadvantages. In this section, a few
of them are outlined and some hints on how they can be dealt with are
provided.
\subsection*{Identifier-Name Blow-Up}
One particular problem with the advanced use of \Cplusplus templates is that the
canonical identifier names for types and methods quickly become really
long and unintelligible. For example, a typical error message
generated using GCC 4.5 and \Dune-PDELab looks like this
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize, numbersep=5pt]
test_pdelab.cc:171:9: error: no matching function for call to Dune::\
PDELab::GridOperatorSpace<Dune::PDELab::PowerGridFunctionSpace<Dune::\
PDELab::GridFunctionSpace<Dune::GridView<Dune::DefaultLeafGridViewTraits\
<const Dune::UGGrid<3>, (Dune::PartitionIteratorType)4u> >, Dune::\
PDELab::Q1LocalFiniteElementMap<double, double, 3>, Dune::PDELab::\
NoConstraints, Ewoms::PDELab::BoxISTLVectorBackend<Ewoms::Properties::\
TTag::LensProblem> >, 2, Dune::PDELab::GridFunctionSpaceBlockwiseMapper>\
, Dune::PDELab::PowerGridFunctionSpace<Dune::PDELab::GridFunctionSpace<\
Dune::GridView<Dune::DefaultLeafGridViewTraits<const Dune::UGGrid<3>, \
(Dune::PartitionIteratorType)4u> >, Dune::PDELab::Q1LocalFiniteElementMap\
<double, double, 3>, Dune::PDELab::NoConstraints, Ewoms::PDELab::\
BoxISTLVectorBackend<Ewoms::Properties::TTag::LensProblem> >, 2, Dune::\
PDELab::GridFunctionSpaceBlockwiseMapper>, Ewoms::PDELab::BoxLocalOperator\
<Ewoms::Properties::TTag::LensProblem>, Dune::PDELab::\
ConstraintsTransformation<long unsigned int, double>, Dune::PDELab::\
ConstraintsTransformation<long unsigned int, double>, Dune::PDELab::\
ISTLBCRSMatrixBackend<2, 2>, true>::GridOperatorSpace()
\end{lstlisting}
This seriously complicates diagnostics. Although there is no full
solution to this problem yet, an effective way of dealing with such
kinds of error messages is to ignore the type information and to just
look at the location given at the beginning of the line. If nested
templates are used, the lines printed by the compiler above the actual
error message specify how exactly the code was instantiated (the lines
starting with ``\texttt{instantiated from}''). In this case it is
advisable to look at the innermost source code location of ``recently
added'' source code.
\subsection*{Proliferation of Template Parameters}
Templates often need a large number of template parameters. For
example, the error message above was produced by the following
snipplet:
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize,numbers=left,numberstyle=\tiny, numbersep=5pt]
int main()
{
enum {numEq = 2};
enum {dim = 3};
typedef Dune::UGGrid<dim> Grid;
typedef Grid::LeafGridView GridView;
typedef Dune::PDELab::Q1LocalFiniteElementMap<double,double,dim> FEM;
typedef TTAG(LensProblem) TypeTag;
typedef Dune::PDELab::NoConstraints Constraints;
typedef Dune::PDELab::GridFunctionSpace<
GridView, FEM, Constraints, Ewoms::PDELab::BoxISTLVectorBackend<TypeTag>
>
doubleGridFunctionSpace;
typedef Dune::PDELab::PowerGridFunctionSpace<
doubleGridFunctionSpace,
numEq,
Dune::PDELab::GridFunctionSpaceBlockwiseMapper
>
GridFunctionSpace;
typedef typename GridFunctionSpace::ConstraintsContainer<double>::Type
ConstraintsTrafo;
typedef Ewoms::PDELab::BoxLocalOperator<TypeTag> LocalOperator;
typedef Dune::PDELab::GridOperatorSpace<
GridFunctionSpace,
GridFunctionSpace,
LocalOperator,
ConstraintsTrafo,
ConstraintsTrafo,
Dune::PDELab::ISTLBCRSMatrixBackend<numEq, numEq>,
true
>
GOS;
GOS gos; // instantiate grid operator space
}
\end{lstlisting}
Although the code above is not really intuitivly readable, this does
not pose a severe problem as long as the type (in this case the grid
operator space) needs to be specified exactly once in the whole
program. If, on the other hand, it needs to be consistend over
multiple locations in the source code, measures have to be taken in
order to keep the code maintainable.
\section{Traits Classes}
A classic approach to reducing the number of template parameters is to
gather all the arguments in a special class, a so-called traits
class. Instead of writing
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize,numbers=left,numberstyle=\tiny, numbersep=5pt]
template <class A, class B, class C, class D>
class MyClass {};
\end{lstlisting}
one can use
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize,numbers=left,numberstyle=\tiny, numbersep=5pt]
template <class Traits>
class MyClass {};
\end{lstlisting}
where the \texttt{Traits} class contains public type definitions for
\texttt{A}, \texttt{B}, \texttt{C} and \texttt{D}, e.g.
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize,numbers=left,numberstyle=\tiny, numbersep=5pt]
struct MyTraits
{
typedef float A;
typedef double B;
typedef short C;
typedef int D;
};
\end{lstlisting}
\noindent
As there is no free lunch, the traits approach comes with a few
disadvantages of its own:
\begin{enumerate}
\item Hierarchies of traits classes are problematic. This is due to
the fact that each level of the hierarchy must be self-contained. As
a result, it is impossible to define parameters in the base class
which depend on parameters which only later get specified by a
derived traits class.
\item Traits quickly lead to circular dependencies. In practice
this means that traits classes can not extract any information from
templates which get the traits class as an argument -- even if the
extracted information does not require the traits class.
\end{enumerate}
\noindent
To see the point of the first issue, consider the following:
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize,numbers=left,numberstyle=\tiny, numbersep=5pt]
struct MyBaseTraits {
typedef int Scalar;
typedef std::vector<Scalar> Vector;
typedef std::list<Scalar> List;
typedef std::array<Scalar> Array;
typedef std::set<Scalar> Set;
};
struct MyDoubleTraits : public MyBaseTraits {
typedef double Scalar;
};
int main() {
MyDoubleTraits::Vector v{1.41421, 1.73205, 2};
for (int i = 0; i < v.size(); ++i)
std::cout << v[i]*v[i] << std::endl;
}
\end{lstlisting}
Contrary to what is intended, \texttt{v} is a vector of integers. This
problem can not be solved using static polymorphism, either, since it
would lead to a cyclic dependency between \texttt{MyBaseTraits} and
\texttt{MyDoubleTraits}.
The second issue is illuminated by the following example, where one
would expect the \texttt{MyTraits:: VectorType} to be \texttt{std::vector<double>}:
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize,numbers=left,numberstyle=\tiny, numbersep=5pt]
template <class Traits>
class MyClass {
public: typedef double ScalarType;
private: typedef typename Traits::VectorType VectorType;
};
struct MyTraits {
typedef MyClass<MyTraits>::ScalarType ScalarType;
typedef std::vector<ScalarType> VectorType
};
\end{lstlisting}
Although this example seems to be quite pathetic, in practice it is
often useful to specify parameters in such a way.
% TODO: section about separation of functions, parameters and
% independent variables. (e.g. the material laws: BrooksCorey
% (function), BrooksCoreyParams (function parameters), wetting
% saturation/fluid state (independent variables)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,217 @@
\documentclass[11pt,a4paper,headinclude,footinclude,DIV16]{scrreprt}
\usepackage[automark]{scrpage2}
\usepackage[ansinew]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{booktabs}
\usepackage{theorem}
\usepackage{color}
\usepackage{listings}
\definecolor{bashgray}{gray}{0.92}
\definecolor{cppgray}{gray}{0.95}
\lstset{language=C++, basicstyle=\ttfamily,
keywordstyle=\color{black}\bfseries, tabsize=4, stringstyle=\ttfamily,
extendedchars=true, escapeinside={/*@}{@*/}}
% for listings of bash code in install.tex
\lstdefinestyle{Bash}
{language=Bash,
backgroundcolor=\color{bashgray},
basicstyle=\ttfamily\small,
numbers=none,
captionpos=b,
tabsize=4,
breaklines=true,
frame=single,
rulecolor=\color{bashgray},
framerule=1pt,
framesep=1pt,
rulesep=0pt,
aboveskip=\bigskipamount,
belowskip=\bigskipamount
}
% for listings of eWoms code
\lstdefinestyle{eWomsCode}
{language=C++,
basicstyle=\ttfamily\scriptsize,
backgroundcolor=\color{bashgray},
rulecolor=\color{bashgray},
numbers=left,
numberstyle=\tiny,
numbersep=5pt,
breaklines=true
}
\lstset{showstringspaces=false,
breaklines=true}
\usepackage[
pdfpagelabels=true,
%draft,
final,
bookmarks=true,
bookmarksnumbered=true,
bookmarksopen=true,
bookmarksopenlevel=1,
breaklinks=true,
colorlinks=true,
hyperindex=true,
linkcolor=black,
citecolor=black,
urlcolor=black,
pdfpagelayout=SinglePage,
%ps2pdf
%dvips
%dvipdf
%pdftex
]{hyperref}
\usepackage{psfrag}
\usepackage{makeidx}
\usepackage{graphicx}
\usepackage{xspace}
\usepackage{relsize}
\usepackage[htt]{hyphenat}
\usepackage{lscape}
\usepackage{enumerate}
\usepackage{rotating}
\usepackage{subfig}
\usepackage{units}
\usepackage{url}
\usepackage{breakurl}
\ifpdf
\usepackage{auto-pst-pdf}
\fi
\usepackage{pstricks}
\usepackage[normalem]{ulem}
\usepackage{tabularx}
\newcommand{\snakeline}{%
% {\uwave{\makebox[\linewidth]{\mbox{}}}}
\uwave{\mbox{}}
}
\usepackage{layout}
\usepackage[english]{babel}
\DeclareGraphicsExtensions{.eps, .jpg}
% Dune occuring in text
\newcommand{\Dune}{{DUNE}\xspace}
% ewoms occuring in text
\newcommand{\Dumux}{\texorpdfstring{Du\-Mu$^\text{x}$\xspace}{DuMuX}}
% eWoms occuring in text
\newcommand{\eWoms}{eWoms\xspace}
% beautify C++
\DeclareRobustCommand\Cplusplus{\texorpdfstring{C\raisebox{2pt}{{\relsize{-3}++}}\xspace}{C++}}
\newcommand{\porosity}{\phi}
\newcommand{\saturation}{S}
\newcommand{\doxyref}[3]{\textnormal{#1}}
\newenvironment{CompactList}
{\begin{list}{}{
\setlength{\leftmargin}{0.5cm}
\setlength{\itemsep}{0pt}
\setlength{\parsep}{0pt}
\setlength{\topsep}{0pt}
\renewcommand{\makelabel}{\hfill}}}
{\end{list}}
\newenvironment{CompactItemize}
{
\begin{itemize}
\setlength{\itemsep}{-3pt}
\setlength{\parsep}{0pt}
\setlength{\topsep}{0pt}
\setlength{\partopsep}{0pt}
}
{\end{itemize}}
\newcommand*\justifyNoHyphen{%
\fontdimen2\font=0.4em% interword space
\fontdimen3\font=0.2em% interword stretch
\fontdimen4\font=0.1em% interword shrink
\fontdimen7\font=0.1em% extra space
\hyphenchar\font=`\-% allowing hyphenation
}
% a new counter
% you can give a label to it and thus reference it
% syntax: \numberThis{printedTextToBeLabeled}{label}
% if you wanted a \newline after a numbered thing, you could just add a empty line after ``\label{#2}''
\newcounter{thingCounter}
\renewcommand{\thethingCounter}{\arabic{thingCounter}}
\newcommand{\numberThis}[2]{%
\refstepcounter{thingCounter}%
\thethingCounter.\ #1 \label{#2}
}
%The theorems
\theorembodyfont{\upshape}
\theoremheaderfont{\sffamily\bfseries}
\newtheorem{exc}{Exercise}[chapter]
\newtheorem{example}[exc]{Example}
\newtheorem{rem}[exc]{Remark}
\newtheorem{lst}{Listing}
\newtheorem{warn}[exc]{Warning}
\newtheorem{justCounting}{}
\DeclareMathOperator{\grad}{grad}
\DeclareMathOperator{\curl}{curl}
\DeclareMathOperator{\Div}{div}
\pagestyle{scrheadings}
\title{
\begin{center}
%\includegraphics[width=0.7\textwidth]{../logo/ewoms_logo_hires_whitebg.eps}
%\\[3cm]
{\Huge The \eWoms Handbook}
\end{center}
}
\author{}
\date{\today}
\publishers{%
{\normalsize \texttt{\url{http://opm-project.org/ewoms}}}\\
}
\makeindex
\begin{document}
\maketitle
\begin{abstract}
\end{abstract}
\tableofcontents
\part{Getting Familiar}
\input{intro}
\input{getting-started}
\input{tutorial}
\part{Concepts and Software Architecture}
\input{designpatterns}
\input{propertysystem}
\input{fluidframework}
\part{Guides}
\input{install}
\input{structure}
\input{guidelines}
\input{models}
\input{newton-in-a-nutshell}
\bibliographystyle{plain}
\bibliography{ewoms-handbook}
\printindex
\end{document}

View File

@ -0,0 +1,436 @@
\chapter{The \eWoms Fluid Framework}
\label{sec:fluidframework}
This chapter discusses the \eWoms fluid framework. \eWoms users who
do not want to write new models and who do not need new fluid
configurations may skip this chapter.
In the chapter, a high level overview over the the principle concepts
is provided first, then some implementation details follow.
\section{Overview of the Fluid Framework}
The \eWoms fluid framework currently features the following concepts
(listed roughly in their order of importance):
\begin{description}
\item[Fluid state:] Fluid states are responsible for representing the
complete thermodynamic configuration of a system at a given spatial
and temporal position. A fluid state always provides access methods
to \textbf{all} thermodynamic quantities, but the concept of a fluid state does not
mandate what assumptions are made to store these thermodynamic
quantities. What fluid states also do \textbf{not} do is to make sure
that the thermodynamic state which they represent is physically
possible.
\item[Fluid system:] Fluid systems express the thermodynamic \textbf{
relations}\footnote{Strictly speaking, these relations are
functions, mathematically.} between quantities. Since functions do
not exhibit any internal state, fluid systems are stateless classes,
i.e. all member functions are \texttt{static}. This is a conscious
decision since the thermodynamic state of the system is expressed by
a fluid state!
\item[Parameter cache:] Fluid systems sometimes require
computationally expensive parameters for multiple relations. Such
parameters can be cached using a so-called parameter
cache. Parameter cache objects are specific for each fluid system
but they must provide a common interface to update the internal
parameters depending on the quantities which changed since the last
update.
\item[Constraint solver:] Constraint solvers are auxiliary tools to
make sure that a fluid state is consistent with some thermodynamic
constraints. All constraint solvers specify a well defined set of
input variables and make sure that the resulting fluid state is
consistent with a given set of thermodynamic equations. See section
\ref{sec:constraint_solvers} for a detailed description of the
constraint solvers which are currently available in \eWoms.
\item[Equation of state:] Equations of state (EOS) are auxiliary
classes which provide relations between a fluid phase's temperature,
pressure, composition and density. Since these classes are only used
internally in fluid systems, their programming interface is
currently ad-hoc.
\item[Component:] Components are fluid systems which provide the
thermodynamic relations for the liquid and gas phase of a single
chemical species or a fixed mixture of species. Their main purpose
is to provide a convenient way to access these quantities from
full-fledged fluid systems. Components are not supposed to be used
by models directly.
\item[Binary coefficient:] Binary coefficients describe the relations
of a mixture of two components. Typical binary coefficients are
\textsc{Henry} coefficients or binary molecular diffusion
coefficients. So far, the programming interface for accessing binary
coefficients has not been standardized in \eWoms.
\end{description}
\section{Fluid States}
Fluid state objects express the complete thermodynamic state of a
system at a given spatial and temporal position.
\subsection{Exported Constants}
\textbf{All} fluid states \textbf{must} export the following constants:
\begin{description}
\item[numPhases:] The number of fluid phases considered.
\item[numComponents:] The number of considered chemical
species or pseudo-species.
\end{description}
\subsection{Accessible Thermodynamic Quantities}
Also, \textbf{all} fluid states \textbf{must} provide the following methods:
\begin{description}
\item[temperature():] The absolute temperature $T_\alpha$ of
a fluid phase $\alpha$.
\item[pressure():] The absolute pressure $p_\alpha$ of a
fluid phase $\alpha$.
\item[saturation():] The saturation $S_\alpha$ of a fluid phase
$\alpha$. The saturation is defined as the pore space occupied by
the fluid divided by the total pore space:
\[
\saturation_\alpha := \frac{\porosity \mathcal{V}_\alpha}{\porosity \mathcal{V}}
\]
\item[moleFraction():] Returns the molar fraction $x^\kappa_\alpha$ of
the component $\kappa$ in fluid phase $\alpha$. The molar fraction
$x^\kappa_\alpha$ is defined as the ratio of the number of molecules
of component $\kappa$ and the total number of molecules of the phase
$\alpha$.
\item[massFraction():] Returns the mass fraction $X^\kappa_\alpha$ of
component $\kappa$ in fluid phase $\alpha$. The mass fraction
$X^\kappa_\alpha$ is defined as the weight of all molecules of a
component divided by the total mass of the fluid phase. It is
related with the component's mole fraction by means of the relation
\[
X^\kappa_\alpha = x^\kappa_\alpha \frac{M^\kappa}{\overline M_\alpha}\;,
\]
where $M^\kappa$ is the molar mass of component $\kappa$ and
$\overline M_\alpha$ is the mean molar mass of a molecule of phase
$\alpha$.
\item[averageMolarMass():] Returns $\overline M_\alpha$, the mean
molar mass of a molecule of phase $\alpha$. For a mixture of $N > 0$
components, $\overline M_\alpha$ is defined as
\[
\overline M_\alpha = \sum_{\kappa=1}^{N} x^\kappa_\alpha M^\kappa
\]
\item[density():] Returns the density $\rho_\alpha$ of the fluid phase
$\alpha$.
\item[molarDensity():] Returns the molar density $\rho_{mol,\alpha}$
of a fluid phase $\alpha$. The molar density is defined by the mass
density $\rho_\alpha$ and the mean molar mass $\overline M_\alpha$:
\[
\rho_{mol,\alpha} = \frac{\rho_\alpha}{\overline M_\alpha} \;.
\]
\item[molarVolume():] Returns the molar volume $v_{mol,\alpha}$ of a
fluid phase $\alpha$. This quantity is the inverse of the molar
density.
\item[molarity():] Returns the molar concentration $c^\kappa_\alpha$
of component $\kappa$ in fluid phase $\alpha$.
\item[fugacity():] Returns the fugacity $f^\kappa_\alpha$ of component
$\kappa$ in fluid phase $\alpha$. The fugacity is defined as
\[
f_\alpha^\kappa := \Phi^\kappa_\alpha x^\kappa_\alpha p_\alpha \;,
\]
where $\Phi^\kappa_\alpha$ is the {\em fugacity
coefficient}~\cite{reid1987}. The physical meaning of fugacity
becomes clear from the equation
\[
f_\alpha^\kappa = f_\alpha^{\kappa,0} \exp\left\{\frac{\zeta^\kappa_\alpha - \zeta^{\kappa,0}_\alpha}{R T_\alpha} \right\} \;,
\]
where $\zeta^\kappa_\alpha$ represents the $\kappa$'s chemical
potential in phase $\alpha$, $R$ stands for the ideal gas constant,
$\zeta^{\kappa,0}_\alpha$ is the chemical potential in a reference
state, $f_\alpha^{\kappa,0}$ is the fugacity in the reference state
and $T_\alpha$ for the absolute temperature of phase $\alpha$. The
fugacity in the reference state $f_\alpha^{\kappa,0}$ is in princle
arbitrary, but in the context of the \eWoms fluid framework, we
assume that it is the same for all fluid phases, i.e.
$f_\alpha^{\kappa,0} = f_\beta^{\kappa,0}$.
Assuming thermal equilibrium, there is a one-to-one mapping between
a component's chemical potential $\zeta^\kappa_\alpha$ and its
fugacity $f^\kappa_\alpha$. With the above assumptions, chemical
equilibrium can thus be expressed by
\[
f^\kappa := f^\kappa_\alpha = f^\kappa_\beta\quad\forall \alpha, \beta
\]
\item[fugacityCoefficient():] Returns the fugacity coefficient
$\Phi^\kappa_\alpha$ of component $\kappa$ in fluid phase $\alpha$.
\item[enthalpy():] Returns specific enthalpy $h_\alpha$ of a fluid
phase $\alpha$.
\item[internalEnergy():] Returns specific internal energy $u_\alpha$
of a fluid phase $\alpha$. The specific internal energy is defined
by the relation
\[
u_\alpha = h_\alpha - \frac{p_\alpha}{\rho_\alpha}
\]
\item[viscosity():] Returns the dynamic viscosity
$\mu_\alpha$ of fluid phase $\alpha$.
\end{description}
\subsection{Available Fluid States}
Currently, the following fluid states are provided by \eWoms:
\begin{description}
\item[NonEquilibriumFluidState:] This is the most general fluid state
supplied. It does not assume thermodynamic equilibrium and thus
stores all phase compositions (using mole fractions), fugacity
coefficients, phase temperatures, phase pressures, saturations and
specific enthalpies.
\item[CompositionalFluidState:] This fluid state is very similar to
the \texttt{Non\-Equilibrium\-Fluid\-State} with the difference that
the \texttt{Compositional\-Fluid\-State} assumes thermodynamic
equilibrium. In the context of multi-phase flow in porous media,
this means that only a single temperature needs to be stored.
\item[ImmisicibleFluidState:] This fluid state assumes that the fluid
phases are immiscible, which implies that the phase compositions and
the fugacity coefficients do not need to be stored explicitly.
\item[PressureOverlayFluidState:] This is a so-called {\em overlay}
fluid state. It allows to set the pressure of all fluid phases but
forwards everything else to another fluid state.
\item[SaturationOverlayFluidState:] This fluid state is like the
\texttt{PressureOverlayFluidState}, except that the phase
saturations are settable instead of the phase pressures.
\item[TempeatureOverlayFluidState:] This fluid state is like the
\texttt{PressureOverlayFluidState}, except that the temperature is
settable instead of the phase pressures. Note that this overlay
state assumes thermal equilibrium regardless of underlying fluid
state.
\item[CompositionOverlayFluidState:] This fluid state is like the
\texttt{PressureOverlayFluidState}, except that the phase
composition is settable (in terms of mole fractions) instead of the
phase pressures.
\end{description}
\section{Fluid Systems}
Fluid systems express the thermodynamic relations between the
quantities of a fluid state.
\subsection{Parameter Caches}
All fluid systems must export a type for their \texttt{ParameterCache}
objects. Parameter caches can be used to cache parameter that are
expensive to compute and are required in multiple thermodynamic
relations. For fluid systems which do need to cache parameters,
\eWoms provides a \texttt{NullParameterCache} class.
The actual quantities stored by parameter cache objects are specific
to the fluid system and no assumptions on what they provide should be
made outside of their fluid system. Parameter cache objects provide a
well-defined set of methods to make them coherent with a given fluid
state, though. These update are:
\begin{description}
\item[updateAll(fluidState, except):] Update all cached quantities for
all phases. The \texttt{except} argument contains a bit field of the
quantities which have not been modified since the last call to a
\texttt{update()} method.
\item[updateAllPresures(fluidState):] Update all cached quantities
which depend on the pressure of any fluid phase.
\item[updateAllTemperatures(fluidState):] Update all cached quantities
which depend on temperature of any fluid phase.
\item[updatePhase(fluidState, phaseIdx, except):] Update all cached
quantities for a given phase. The quantities specified by the
\texttt{except} bit field have not been modified since the last call
to an \texttt{update()} method.
\item[updateTemperature(fluidState, phaseIdx):] Update all cached
quantities which depend on the temperature of a given phase.
\item[updatePressure(fluidState, phaseIdx):] Update all cached
quantities which depend on the pressure of a given phase.
\item[updateComposition(fluidState, phaseIdx):] Update all cached
quantities which depend on the composition of a given phase.
\item[updateSingleMoleFraction(fluidState, phaseIdx, compIdx):] Update
all cached quantities which depend on the value of the mole fraction
of a component in a phase.
\end{description}
Note, that the parameter cache interface only guarantees that if a
more specialized \texttt{update()} method is called, it is not slower
than the next more-general method (e.g. calling
\texttt{updateSingleMoleFraction()} may be as expensive as
\texttt{updateAll()}). It is thus advisable to rather use a more
general \texttt{update()} method once than multiple calls to
specialized \texttt{update()} methods.
To make usage of parameter caches easier for the case where all cached
quantities ought to be re-calculated if a quantity of a phase was
changed, it is possible to only define the \texttt{updatePhase()}
method and derive the parameter cache from
\texttt{Ewoms::ParameterCacheBase}.
\subsection{Exported Constants and Capabilities}
Besides providing the type of their \texttt{ParameterCache} objects,
fluid systems need to export the following constants and auxiliary
methods:
\begin{description}
\item[numPhases:] The number of considered fluid phases.
\item[numComponents:] The number of considered chemical (pseudo-)
species.
\item[init():] Initialize the fluid system. This is usually used to
tabulate some quantities
\item[phaseName():] Given the index of a fluid phase, return its name
as human-readable string.
\item[componentName():] Given the index of a component, return its
name as human-readable string.
\item[isLiquid():] Return whether the phase is a liquid, given the
index of a phase.
\item[isIdealMixture():] Return whether the phase is an ideal mixture,
given the phase index. In the context of the \eWoms fluid
framework a phase $\alpha$ is an ideal mixture if, and only if, all
its fugacity coefficients $\Phi^\kappa_\alpha$ do not depend on the
phase composition. (Although they might very well depend on
temperature and pressure.)
\item[isIdealGas():] Return whether a phase $\alpha$ is an ideal gas,
i.e. it adheres to the relation
\[
p_\alpha v_{mol,\alpha} = R T_\alpha \;,
\]
with $R$ being the ideal gas constant.
\item[isCompressible():] Return whether a phase $\alpha$ is
compressible, i.e. its density depends on pressure $p_\alpha$.
\item[molarMass():] Given a component index, return the molar mass of
the corresponding component.
\end{description}
\subsection{Thermodynamic Relations}
Fluid systems have been explicitly designed to provide as few
thermodynamic relations as possible. A full-fledged fluid system thus
only needs to provide the following thermodynamic relations:
\begin{description}
\item[density():] Given a fluid state, an up-to-date parameter cache
and a phase index, return the mass density $\rho_\alpha$ of the
phase.
\item[fugacityCoefficient():] Given a fluid state, an up-to-date
parameter cache as well as a phase and a component index, return the
fugacity coefficient $\Phi^\kappa_\alpha$ of a the component for the
phase.
\item[viscosity():] Given a fluid state, an up-to-date parameter cache
and a phase index, return the dynamic viscosity $\mu_\alpha$ of the
phase.
\item[diffusionCoefficient():] Given a fluid state, an up-to-date
parameter cache, a phase and a component index, return the calculate
the molecular diffusion coefficient for the component in the fluid
phase.
Molecular diffusion of a component $\kappa$ in phase $\alpha$ is
caused by a gradient of the chemical potential. Using some
simplifying assumptions~\cite{reid1987}, they can be also expressed
in terms of mole fraction gradients, i.e. the equation used for mass
fluxes due to molecular diffusion is
\[
J^\kappa_\alpha = - \rho_{mol,\alpha} D^\kappa_\alpha\ \mathbf{grad} x^\kappa_\alpha\;,
\]
where $\rho_{mol,\alpha}$ is the molar density of phase $\alpha$,
$x^\kappa_\alpha$ is the mole fraction of component $\kappa$ in
phase $\alpha$, $D^\kappa_\alpha$ is the diffusion coefficient and
$J^\kappa_\alpha$ is the diffusive flux.
\item[enthalpy():] Given a fluid state, an up-to-date parameter cache
and a phase index, this method calulates the specific enthalpy
$h_\alpha$ of the phase.
\item[thermalConductivity:] Given a fluid state, an up-to-date
parameter cache and a phase index, this method returns the thermal
conductivity $\lambda_\alpha$ of the fluid phase. The thermal
conductivity is defined by means of the relation
\[
\dot Q = \lambda_\alpha \mathbf{grad}\;T_\alpha \;,
\]
where $\dot Q$ is the heat flux caused by the temperature gradient
$\mathbf{grad}\;T_\alpha$.
\item[heatCapacity():] Given a fluid state, an up-to-date parameter
cache and a phase index, this method computes the isobaric heat
capacity $c_{p,\alpha}$ of the fluid phase. The isobaric heat
capacity is defined as the partial derivative of the specific
enthalpy $h_\alpha$ to the fluid pressure:
\[
c_{p,\alpha} = \frac{\partial h_\alpha}{\partial p_\alpha}
\]
% TODO: remove the heatCapacity() method??
\end{description}
Fluid systems may chose not to implement some of these methods and
throw an exception of type \lstinline{Dune::NotImplemented} instead. Obviously,
such fluid systems cannot be used for models that depend on those
methods.
\section{Constraint Solvers}
\label{sec:constraint_solvers}
Constraint solvers connect the thermodynamic relations expressed by
fluid systems with the thermodynamic quantities stored by fluid
states. Using them is not mandatory for models, but given the fact
that some thermodynamic constraints can be quite complex to solve,
sharing this code between models makes sense. Currently, \eWoms
provides the following constraint solvers:
\begin{description}
\item[CompositionFromFugacities:] This constraint solver takes all
component fugacities, the temperature and pressure of a phase as
input and calculates the composition of the fluid phase. This means
that the thermodynamic constraints used by this solver are
\[
f^\kappa = \Phi^\kappa_\alpha(\{x^\beta_\alpha \}, T_\alpha, p_\alpha) p_\alpha x^\kappa_\alpha\;,
\]
where ${f^\kappa}$, $T_\alpha$ and $p_\alpha$ are fixed values.
\item[ComputeFromReferencePhase:] This solver brings all
fluid phases into thermodynamic equilibrium with a reference phase
$\beta$, assuming that all phase temperatures and saturations have
already been set. The constraints used by this solver are thus
\begin{eqnarray*}
f^\kappa_\beta = f^\kappa_\alpha = \Phi^\kappa_\alpha(\{x^\beta_\alpha \}, T_\alpha, p_\alpha) p_\alpha x^\kappa_\alpha\;, \\
p_\alpha = p_\beta + p_{c\beta\alpha} \;,
\end{eqnarray*}
where $p_{c\beta\alpha}$ is the capillary pressure between the
fluid phases $\beta$ and $\alpha$.
\item[NcpFlash:] This is a so-called flash solver. A flash solver
takes the total mass of all components per volume unit and the phase
temperatures as input and calculates all phase pressures,
saturations and compositions. This flash solver works for an
arbitrary number of phases $M > 0$ and components $N \geq M - 1$. In
this case, the unknown quantities are the following:
\begin{itemize}
\item $M$ pressures $p_\alpha$
\item $M$ saturations $\saturation_\alpha$
\item $M\cdot N$ mole fractions $x^\kappa_\alpha$
\end{itemize}
This sums up to $M\cdot(N + 2)$. The equations side of things
provides:
\begin{itemize}
\item $(M - 1)\cdot N$ equations stemming from the fact that the
fugacity of any component is the same in all phases, i.e.
\[
f^\kappa_\alpha = f^\kappa_\beta
\]
holds for all phases $\alpha, \beta$ and all components $\kappa$.
\item $1$ equation comes from the fact that the whole pore space is
filled by some fluid, i.e.
\[
\sum_{\alpha=1}^M \saturation_\alpha = 1
\]
\item $M - 1$ constraints are given by the capillary pressures:
\[
p_\beta = p_\alpha + p_{c\beta\alpha} \;,
\]
for all phases $\alpha$, $\beta$
\item $N$ constraints come the fact that the total mass of each
component is given:
\[
c^\kappa_{tot} = \sum_{\alpha=1}^M x_\alpha^\kappa\;\rho_{mol,\alpha} = const
\]
\item And finally $M$ model assumptions are used. This solver uses
the NCP constraints proposed in~\cite{LHHW2011}:
\[
0 = \mathrm{min}\{\saturation_\alpha, 1 - \sum_{\kappa=1}^N x_\alpha^\kappa\}
\]
\end{itemize}
The number of equations also sums up to $M\cdot(N + 2)$. Thus, the
system of equations is closed.
\item[ImmiscibleFlash:] This is a flash solver assuming immiscibility
of the phases. It is similar to the \texttt{NcpFlash} solver but a
lot simpler.
\item[MiscibleMultiphaseComposition:] This solver calculates the
composition of all phases provided that each of the phases is
potentially present. Currently, this solver does not support
non-ideal mixtures.
\end{description}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "ewoms-handbook"
%%% End:

View File

@ -0,0 +1,21 @@
\chapter{Set-up and basic workflows}
This chapter is aimed at setting up a development environment for
\eWoms and to equip you with a rough understanding of the basic
workflows used for developing the software. We will first have a
brief look at the installation procedure; After that, we will run a
sample simulation and briefly discuss how to visualize its results.
Be aware, that this is only a very streamlined version of the \eWoms
development workflow, so make yourself confident with the tools
introduced in this section before you delve into the \Cplusplus code
in the next chapter.
\input{quick-install}
\input{quickstart-guide}
\input{parameters}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "ewoms-handbook"
%%% End:

View File

@ -0,0 +1,90 @@
\chapter{Coding Style Guidelines}
\label{guidelines}
An important characteristic of source code is that it is written only
once but usually it is read many times (e.g. when debugging things,
adding features, etc.). For this reason, good programming frameworks
always aim to be as readable as possible, even if comes with higher
effort to write them in the first place. The remainder of this section
is very similar to the \Dune coding guidelines found at the \Dune
website~\cite{DUNE-HP}. These guidelines are also strongly recommended
for working with \eWoms. Some of these coding style rules may seem
like splitting hairs to you, but they do make it much easier for
everybody to work on code that has not been written by oneself.
\begin{itemize}
\item Naming:
\begin{itemize}
\item Comments: They are helpful! Use comments extensively to explain
what your code does, but please refrain from adding trivial
comments. Trivial comments are, for example comments that only
parrot the source code (``this method sets a'' as the comment for a
method called \texttt{setA()}), or comments that explain language
features (``if b is true then a is c else d'' for the statement
\texttt{a = b?c:d}).
\item All comments, documentation and variable or type names are
exclusivly using the English language.
\item Variables: Names for variables should only feature letters and
digits. The first letter should be lower case. If your variable
names consists of several words, then the first letter of each new
word should be capitalized.
\item Variables and methods should be named as self-explanatory as
possible. Especially, this means abbreviations should be avoided
(for example, use 'saturation' in stead of 'S')
\item Method parameters which are not self-explanatory should always
have a meaningful comment a at calling sites. Example:
\begin{lstlisting}[style=eWomsCode]
localResidual.eval(/*includeBoundaries=*/true);
\end{lstlisting}
\item Private attributes: Names of private attributes should end with
an underscore and are supposed to be the only variables that contain
underscores.
\item Typenames: For typenames (classes, structures, typedefs, etc),
the same rules as for variables apply. The only difference is that
the first letter should be a capital one.
\item Macros: The use of preprocessor macros is strongly
discouraged. If you have to use them for whatever reason, please use
capital letters only.
\item Guardian macros: Every header file traditionally begins with the
definition of a preprocessor macro that is used to make sure that
the header file is only included once. If your header file is
called 'myheaderfile.hh', this constant should be named
\texttt{EWOMS\_MYHEADERFILE\_HH}.
\item Files: File names should exclusively consist of lower case
letters. Header files get the suffix .hh, implementation files the
suffix .cc
\end{itemize}
\item Documentation: \eWoms, as any software project of similar
complexity, will stand and fall with the quality of its
documentation. Therefore, it is of paramount importance that you
document everything you do well! We use the doxygen system to
extract easily-readable documentation from the source code. Please
use its syntax everywhere. In particular, please comment
\textbf{all}
\begin{itemize}
\item Method parameters
\item Template parameters
\item Return values
\item Exceptions thrown by a method
\end{itemize}
Since we all know that writing documentation is not well-liked and is
frequently defered to some vague 'next week', we herewith proclaim
the Doc-Me Dogma . It goes like this: Whatever you do, and in
whatever hurry you happen to be, please document everything at least
with a {\verb /** $\backslash$todo Please doc me! */}. That way at
least the absence of documentation is documented, and it is easier to
get rid of it systematically.
\item Exceptions: The use of exceptions for error handling is
encouraged. Until further notice, all exceptions thrown are derived
from \texttt{Dune::Exception}.
\item Debugging code: Code which is only there to ease the debugging
process should always be switched off if the preprocessor macro
NDEBUG is defined. In particular, all assertations are automatically
removed. Use those assertations freely!
\end{itemize}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "ewoms-handbook"
%%% End:

379
doc/handbook/install.tex Normal file
View File

@ -0,0 +1,379 @@
\chapter{Detailed Installation Instructions}
\label{install}
\section{Preliminary remarks}
In this section about the installation of \eWoms it is assumed that
you work on a Unix or Linux compatible operating system and that you
are familiar with the use of a command line shell. Installation means
that you unpack \Dune together with \eWoms in a certain directory.
Then, you compile it in that directory tree in which you do the
further work, too. You also should know how to install new software
packages or you should have a person on hand who assist you with
that. In section \ref{sec:prerequisites} we list some prerequisites
for running \Dune and \eWoms. Please make sure to fulfill them before
you proceed. In addition, section \ref{sec:external-modules-libraries}
provides some details on optional libraries and modules.
In a technical sense \eWoms is a module of \Dune. Thus, the
installation procedure of \eWoms is the same as that of \Dune (besides
using different locations to retieve the source code). Details
regarding the installation of \Dune are provided on the \Dune
website~\cite{DUNE-INST}. If you are interested in more details about
the build system that is used, they can be found in the {\Dune}
build system howto \cite{DUNE-BS}.
All \Dune modules, including \eWoms, get extracted into a common
directory. In the following, we refer to that directory as {\Dune}
base directory or, in short, as {\Dune}-base. If it is used as
directory path of a shell command it is typed as
\texttt{dune-base}. For the actual location of the {\Dune} base
directory on your file system, you may chose any valid directory name for
which you have write permissions.
Source code files for each \Dune module are contained in their own
subdirectory within {\Dune}-base. We name this directory of a certain
module \emph{module base directory} or \texttt{module-base}
if it is a directory path, e.\,g. for the module \texttt{ewoms} these
names are \emph{ewoms base directory} respective
\texttt{ewoms-base}. The real directory names for the
modules can be chosen arbitrarily. In this manual they are the same as
the module name or the module name extended by a version number
suffix. The name of each \Dune module is defined in the file
\texttt{dune.module}, which is in the base directory of the respective
module. This should not be changed by the user. It is allowed to have
own files and directories in \Dune-base, which are not related to
\Dune's needs.
After installing source code for all relevant \Dune modules including
\eWoms, \Dune is being built by the shell-command \texttt{dunecontrol}
which is part of the \Dune build system. The \Dune build system is a
front-end of to the GNU build system adapted to the needs of \Dune.
\section{Prerequisites} \label{sec:prerequisites}
The GNU compiler collection with \Cplusplus support (\texttt{g++}) and
the tools of the GNU build system \cite{GNU-BS}, also known as GNU
autotools (\texttt{autoconf}, \texttt{automake}, \texttt{autogen},
\texttt{libtool}), as well as the GNU variant of \texttt{make} called
gmake must be available in a recent enough version. For example Ubuntu
Linux provides these tools by means of the packages \texttt{autoconf},
\texttt{automake}, \texttt{libtool} and the package
\texttt{build-essential} includes the \Cplusplus compiler
\texttt{g++} and \texttt{make}.
At the time of writing this manual, the minumum version required for
\texttt{g++} is 4.4.0, \texttt{automake} the documentation by setting the switch
\texttt{--disable-documentation} in the \texttt{CONFIGURE\_FLAGS} of
the building options (see Chapter \ref{buildIt}). Additional parts of
documentation are contained within the source code files as specially
formatted comments. Extracting them can be done using the tool
\texttt{doxygen} (version $\geqslant$ 1.8.2 works). See for this
optional step section \ref{sec:build-doxy-doc}.
Depending on whether you are going to use external libraries and
modules for additional \Dune features, additional software packages
may be required. Some hints on that are given in Section
\ref{sec:external-modules-libraries}.
To access the git or subversion software repositories, git and
subversion clients are required. We recommend to use the git
command-line client \texttt{git} version 1.7.12 or newer with the
subversion integration plugin \texttt{git-svn} enabled~\cite{GIT-HP}.
\begin{table}
\centering
\caption{Ubuntu package names for Ubuntu 12.04}
\begin{tabular}{llll}
\toprule
\textbf{purpose} & \textbf{package names} \\
\midrule
general: & git & git-svn & libtool \\
& automake & build-essential & libboost-all-dev \\
& texlive-latex-base & doxygen & csh\\
& gfortran & \\
\midrule
for alberta: & freeglut3-dev & \\
\midrule
for parallel use: & openmpi-common & mpi-default-bin & mpi-default-dev \\
\midrule
for parallel UG: & flex & bison & \\
\midrule
for parallel alberta: & libblas-dev &\\
\midrule
for debugging: & valgrind &\\
\bottomrule
\end{tabular}
\label{tbl:ubuntu-pkg}
\end{table}
\begin{table}
\centering
\caption{Package names for openSUSE 12.2. For this distribution, the {\em science} package repository needs to be added. The science repository is available from \url{http://download.opensuse.org/repositories/science/openSUSE_12.2/}. }
\begin{tabular}{llll}
\toprule
\textbf{purpose} & \textbf{package names} \\
\midrule
git & git-svn & dune-istl-devel & dune-grid-devel \\
dune-localfunctions-devel & \\
\bottomrule
\end{tabular}
\label{tbl:opensuse-pkg}
\end{table}
\section{Obtaining source code for \Dune and \eWoms}
As stated above, the \eWoms is based on the \Dune release 2.2,
comprising the core modules \texttt{dune-common},
\texttt{dune-geometry}, \texttt{dune-grid}, \texttt{dune-istl} and
\texttt{dune-localfunctions}. For working with \eWoms, these modules
are required.
Two possibilities exist to get the source code of \Dune and \eWoms.
Firstly, released versions \Dune and \eWoms can be downloaded as tar
files from the \Dune and \eWoms websites. They have to be extracted as
described in the next paragraph. Secondly, the most recent source
code can be obtained by directly downloading it from its respective
source-code repository. This method is described in the subsequent
section.
\paragraph{Obtaining the software by installing tar files}
The slightly old-fashionedly named tape-archive-file, shortly named
tar file or tarball, is a common file format for distributing
collections of files contained within these archives. The extraction
from the tar files is done as follows: Download the tarballs from the
respective \Dune~\cite{DUNE-HP} (version 2.2.0) and
\eWoms~\cite{EWOMS-HP} websites. Then, create the {\Dune} base
directory, named \texttt{~/src} in the example below. Then, extract the
content of the tar files, e.\,g. with the command-line program
\texttt{tar}. This can be achieved by the following shell
commands. Replace \texttt{path\_to\_tarball} with the directory name
where the downloaded files are actually located. After extraction,
the actual name of the \emph{ewoms base directory} is
\texttt{ewoms-2.2}.
\begin{lstlisting}[style=Bash]
$ mkdir ~/src
$ cd ~/src
$ tar xzvf path_to_tarball_of/dune-common-2.2.0.tar.gz
$ tar xzvf path_to_tarball_of/dune-grid-2.2.0.tar.gz
$ tar xzvf path_to_tarball_of/dune-geometry-2.2.0.tar.gz
$ tar xzvf path_to_tarball_of/dune-istl-2.2.0.tar.gz
$ tar xzvf path_to_tarball_of/dune-localfunctions-2.2.0.tar.gz
$ tar xzvf path_to_tarball_of/ewoms-2.2.0.tar.gz
\end{lstlisting}
\paragraph{Obtaining \Dune and \eWoms from software repositories}
Direct access to a software repositories for downloading code can be
convenient to always follow the changes of done to the software
project. Usually, source code repositories are structured in
branches. One of these branches is commonly used to include the latest
features of the software, and there is normally one branch for each
release which only receives fixes for bug which have been discovered
after the software was released. The following text describes how to
retrieve the source code of \Dune and \eWoms from such release
branches.
The \Dune project uses Apache Subversion~\cite{APACHE-SUBVERSION-HP}
to manage its software repositories, while \eWoms -- being part of the
open porous media project -- opted to use the git source code
management system~\cite{GIT-HP}. Fortunately, git ships with a
subversion plugin, so all modules can be managed using git.
In the technical language of Apache Subversion \emph{cloning a certain
software repository} means nothing more then fetching a local copy
of the software repository and placing it on the local file system.
In addition to the software some more files for the use of the
software revision control system itself are created. They are kept in
a directory named \texttt{.git} at the base directory of the cloned
software repository.
The installation procedure is structured as follows: Create a {\Dune} base
directory (named \texttt{~/src} in the lines below). Then, enter the
previously created directory and check out the desired modules. As
you see below, the check-out uses two different servers for getting
the sources, one for \Dune and one for \eWoms. The \Dune modules of
the stable 2.2 release branch are cloned similarly as described on the
\Dune website~\cite{DUNE-DOWNLOAD-SVN}:
\begin{lstlisting}[style=Bash]
mkdir ~/src
cd ~/src
for DUNE_MODULE in common geometry grid istl localfunctions; do
git svn clone \
https://svn.dune-project.org/svn/dune-$DUNE_MODULE/branches/release-2.2 \
dune-$DUNE_MODULE
done
\end{lstlisting}
The newest and maybe unstable developments are also provided in these
repositories in a folder called \emph{trunk}. Please check the \Dune
website \cite{DUNE-DOWNLOAD-SVN} for further information. However, the
current \eWoms release is based on the stable 2.2 \Dune release and it
might misbehave using the the newest version of \Dune.
The \eWoms module is checked out as described below (see also the
\eWoms website \cite{EWOMS-HP}). Its source tree has to be created in
the \Dune-base directory, where the \Dune modules have also been
cloned into. Subsequently, the next command is executed there,
too. The directory which holds the \eWoms module is called
\texttt{ewoms} here.
\begin{lstlisting}[style=Bash]
cd ~/src
git clone git://github.com/OPM/ewoms.git ewoms
\end{lstlisting}
\section{Building the doxygen documentation}
\label{sec:build-doxy-doc}
Doxygen documentation is done by especially formatted comments
integrated in the source code, which can get extracted by the program
\texttt{doxygen}. Beside extracting these comments, \texttt{doxygen}
builds up a web-browsable code structure documentation like class
hierarchy of code displayed as graphs, see \cite{DOXYGEN-HP}.
Building the doxygen documentation of a module is done as follows,
provided the program \texttt{doxygen} is installed: Set in building
options the \texttt{--enable-doxygen} switch. This is either
accomplished by adding it in \texttt{dunecontrol} options-file to
\texttt{CONFIGURE\_FLAGS}, or by adding it to \texttt{dunecontrol}'s
command-line-argument \texttt{--configure-opts}. After running
\texttt{dunecontrol} enter in module's base directory the subdirectory
\texttt{doc/doxygen}. You then run the command \texttt{doxygen}
within that directory. Point your web browser to the file
\texttt{module-base-directory/doc/doxygen/html/index.html} to read the
generated documentation. For all \Dune-modules that described here,
the doxygen documentation can be generated analogously.
\begin{lstlisting}[style=Bash]
cd ~/src/ewoms/doc/doxygen
doxygen
firefox html/index.html
\end{lstlisting}
\section{Building the \eWoms handbook}
If the \texttt{--enable-documentation} switch has been set in the configure flags of
\texttt{dunecontrol}, watch for a summary line of the build script that reads
\begin{lstlisting}[style=Bash]
Build eWoms handbook....: yes
\end{lstlisting}
If this is the case, the handbook should be automatically build by
\texttt{dunecontrol} and can be found at
\texttt{\$EWOMS\_BASE/doc/handbook/ewoms-handbook.pdf}.
If the summary line says that the handbook is not going to be build,
then you usually have to install additional \LaTeX packages.
\section{External libraries and modules}
\label{sec:external-modules-libraries}
The libraries described below provide additional functionality but are
not generally required to use \eWoms. If you are going to use an
external library, also check the information provided on the \Dune
website~\cite{DUNE-EXT-LIB} for additional hints. If you are going to
use an external \Dune module, the website listing external
modules~\cite{DUNE-EXT-MOD} can also be helpful.
Some external libraries have additional dependencies which can also be
used by \Dune. Also, some libraries, such as BLAS or MPI might have
multiple versions installed on the system. To avoid problems, you
should make sure that all external libraries use the same dependencies
as \Dune.
In the following list, you can find some external modules and external
libraries, and some more libraries and tools which are prerequisites
for their use.
\begin{itemize}
\item \textbf{ALBERTA}: External library which can be used as an
additional grid manager. ALBERTA stands for ``\textbf{A}daptive multi \textbf{L}evel finite element toolbox
using \textbf{B}isectioning refinement and \textbf{E}rror control by \textbf{R}esidual
\textbf{T}echniques for scientific \textbf{A}pplications''. Building it requires a
Fortran compiler, for example \texttt{gfortran}. It can be downloaded at:
\texttt{\url{http://www.alberta-fem.de}}.
\item \textbf{ALUGrid}: External library for use as grid. ALUGrid
requires by a \Cplusplus compiler like \texttt{g++} to be build. If
you want to build a parallel version, you will need an MPI library
like, for example \texttt{openmpi}, installed on your system. The
parallel version needs also a graph partitioner, such as
\texttt{METIS}.
Download:
\texttt{\url{http://aam.mathematik.uni-freiburg.de/IAM/Research/alugrid}}
\item \textbf{SuperLU}: External library for solving linear
equations. SuperLU is a general purpose library for the direct
solution of large, sparse, non-symmetric systems of linear
equations.
Download:
\texttt{\url{http://crd.lbl.gov/~xiaoye/SuperLU}}.
\item \textbf{UG}: External library which can be used as an additional
grid manager. UG is a toolbox for \textbf{U}nstructured
\textbf{G}rids: For \eWoms it has to be build by GNU buildsystem and
a \Cplusplus compiler. That's why \Dune specific patches need
applied before use. Building it makes use of the tools
\texttt{lex}/\texttt{yacc} or the GNU variants
\texttt{flex}/\texttt{bison}.
Website:
\texttt{\url{http://atlas.gcsc.uni-frankfurt.de/~ug/}}\\
Further information:
\texttt{\url{http://www.dune-project.org/external_libraries/install_ug.html}}\\
\end{itemize}
The following are dependencies of some of the external libraries. You
will need them depending on which modules of \Dune and which external
libraries you use.
\begin{itemize}
\item \textbf{MPI}: The parallel version of \Dune and also some of the
external dependencies need MPI when they are going to be built for
parallel computing. \texttt{Openmpi} version $\geqslant$ 1.4.2 and
\texttt{MPICH} in a recent version have been reported to work.
\item \textbf{lex/yacc} or \textbf{flex/bison}: These are quite common
developing tools, code generators for lexical analyzers and
parsers. This is a prerequisite for compiling UG.
\item \textbf{BLAS}: Alberta makes use of BLAS (acronym for
``\textbf{B}asic \textbf{L}inear \textbf{A}lgebra
\textbf{S}ubprograms). Thus install GotoBLAS2, ATLAS,
non-optimized BLAS or a BLAS library provided by a computer
vendor. Take care that the installation scripts select the intended
version of BLAS. For further information, see
\texttt{\url{http://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms}}.
\item \textbf{GotoBLAS2}: This is an optimized BLAS library. It does
not provide optimized routines for all modern processors, but quite
a broad range. Also, its license is now open. A Fortran compiler
like \texttt{gfortran} is needed to compile it.
Available at
\texttt{\url{http://www.tacc.utexas.edu/tacc-projects/gotoblas2/}}.
\item \textbf{METIS}: This is a dependency of ALUGrid, if you are
going to run it parallel.
Available for non-commercial use at
\texttt{\url{http://glaros.dtc.umn.edu/gkhome/metis/metis/overview}}
\item \textbf{Compilers}: Besides \texttt{g++} \Dune and \eWoms can
also be built with the \texttt{clang++} compiler originating from
the LLVM project. If you try other compilers, be aware that in addition to a
\Cplusplus compiler, C and Fortran compilers are needed to compile
some external libraries.
\end{itemize}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "ewoms-handbook"
%%% End:

93
doc/handbook/intro.tex Normal file
View File

@ -0,0 +1,93 @@
\chapter{Introduction}
\eWoms~\cite{EWOMS-HP} a generic simulation framework using continuum
mechanical approaches with a focus on multi-phase fluid flow and
transport processes in porous media. \eWoms is also an integral part
of the open porous media initiative~\cite{OPM-HP} for which it
implements the fully-implicit discretization schemes. \eWoms is based
on the source code of the \Dumux~\cite{DUMUX-HP} simulation framework
and aims to be a proper superset of \Dumux when it comes to features,
while at the same time it delivers better performance and a
higher-quality code base. To ease porting features from \Dumux to
\eWoms, the \eWoms source code uses very similar naming and style
conventions as the one of \Dumux.
Besides being a generic simulation framework, \eWoms also aims to to
deliver top-notch computational performance, high flexibility, a sound
software architecture and the ability to run on anything from single
processor systems to highly parallel supercomputers with specialized
hardware architectures. The means to achieve these somewhat
contradictory goals are the thorough use of object oriented design in
conjunction with template programming. These requirements motivated
the decision to implement \eWoms using the \Cplusplus programming
language.
One of the more complex issues when dealing with parallel continuum
models for partial differential equations, is the management of the
grids used for the spatial discretization. To date, no generic and
efficient approach exists for all possible cases, which lead to \eWoms
being build on top of \Dune, the \textbf{D}istributed and
\textbf{U}nified \textbf{N}umerics
\textbf{E}nvironment~\cite{DUNE-HP}. Instead of trying to implement a
grid for everything, \Dune defines a generic \Cplusplus interface to
grids, and provides adapters to several existing grid management
libraries such as UG~\cite{UG-HP}, ALBERTA~\cite{ALBERTA-HP} or
ALUGrid~\cite{ALUGRID-HP}. DUNE also extensively uses template
programming in order to achieve minimal overhead when accessing the
underlying grid libraries\footnote{In fact, the performance penalty
resulting from the use of \Dune's grid interface is usually
negligible~\cite{BURRI2006}.}.
\begin{figure}[hbt]
\centering
\includegraphics[width=.5\linewidth, keepaspectratio]{EPS/dunedesign}
\caption{
\label{fig:dune-design}
A high-level overview of \Dune's design is available on the project's
web site~\cite{DUNE-HP}.
}
\end{figure}
DUNE's grid interface is independent of the spatial dimension of the
underlying grid. For this purpose, it uses the concept of
co-dimensional entities. Roughly speaking, an entity of co-dimension
$0$ constitutes a cell, co-dimension $1$ entities are faces between
cells, co-dimension $1$ are edges, and so on until co-dimension $n$
which are the cell's vertices. The \Dune grid interface generally
assumes that all entities are convex polytopes, which means that it
must be possible to express each entity as the convex hull of a set of
vertices. For the sake of efficiency, all entities are further expressed in terms
of so-called reference elements which are transformed to the actual
spatial incarnation within the grid by a so-called geometry
function. Here, a reference element for an
entity can be thought of as a prototype for the actual grid
entity. For example, if we used a grid which applied hexahedrons as cells,
the reference element for each cell would be the unit cube $[0, 1]^3$
and the geometry function would scale and translate the cube so that
it matches the grid's cell. For a more thorough description of \Dune's
grid definition, see~\cite{BASTIAN2008}.
In addition to the grid interface, \Dune also provides quite a few
additional modules; In the context of this handbook the
\texttt{dune-localfunctions} and \texttt{dune-istl} modules are
probably the most relevant. \texttt{dune-localfunctions} provides a
set of generic finite element shape functions, while
\texttt{dune-istl} is the \textbf{I}terative \textbf{S}olver
\textbf{T}emplate \textbf{L}ibrary and provides generic, highly
optimized linear algebra routines for solving linear systems of
equations.
\eWoms comes in form of a module \Dune module '\texttt{ewoms}'. It
depends on the \Dune core modules \texttt{dune-common},
\texttt{dune-grid}, \texttt{dune-istl}, and on
\texttt{dune-localfunctions}. The main intention of \eWoms is to
provide a framework for an easy and efficient implementation of new
physical models for porous media flow problems, ranging from problem
formulation and the selection of spatial and temporal discretization
schemes as well as nonlinear and linear solvers, to general concepts
for model coupling. Moreover, \eWoms includes ready-to-use numerical
models and a few example applications.
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "ewoms-handbook"
%%% End:

179
doc/handbook/models.tex Normal file
View File

@ -0,0 +1,179 @@
\chapter[Models]{Physical and numerical models}
\section{Physical and mathematical description}
Characteristic of compositional multiphase models is that the phases
are not only matter of a single chemical substance. Instead, their
composition in general includes several species, and for the mass transfer,
the component behavior is quite different from the phase behavior. In the following, we
give some basic definitions and assumptions that are required for the
formulation of the model concept below. As an example, we take a
three-phase three-component system water-NAPL-gas
\cite{A3:class:2002a}. The modification for other multicomponent
systems is straightforward and can be found, e.\ g., in
\cite{A3:bielinski:2006,A3:acosta:2006}.
\subsection{Basic Definitions and Assumptions for the Compositional
Model Concept}
\textbf{Components:}
The term \emph{component} stands for constituents of the phases which
can be associated with a unique chemical species, or, more generally, with
a group of species exploiting similar physical behavior. In this work, we
assume a water-gas-NAPL system composed of the phases water (subscript
$\text{w}$), gas ($\text{g}$), and NAPL ($\text{n}$). These phases are
composed of the components water (superscript $\text{w}$), air
($\text{a}$), and the organic contaminant ($\text{c}$) (see Fig.\
\ref{A3:fig:mundwtrans}).
%
\begin{figure}[hbt]
\centering
\includegraphics[width=0.7\linewidth]{EPS/masstransfer}
\caption{Mass and energy transfer between the phases}
\label{A3:fig:mundwtrans}
\end{figure}
\textbf{Equilibrium:}
For the nonisothermal multiphase processes in porous media under
consideration, we state that the assumption of local thermal
equilibrium is valid since flow velocities are small. We neglect
chemical reactions and biological decomposition and assume chemical
equilibrium. Mechanical equilibrium is not valid in a porous medium,
since discontinuities in pressure can occur across a fluid-fluid
interface due to capillary effects.
\textbf{Notation:} The index $\alpha \in \{\text{w}, \text{n}, \text{g}\}$ refers
to the phase, while the superscript $\kappa \in \{\text{w}, \text{a}, \text{c}\}$ refers
to the component. \\
\begin{tabular}{llll}
$p_\alpha$ & phase pressure & $\phi$ & porosity \\
$T$ & temperature & $K$ & absolute permeability tensor \\
$S_\alpha$ & phase saturation & $\tau$ & tortuosity \\
$x_\alpha^\kappa$ & mole fraction of component $\kappa$ in phase $\alpha$ & $\boldsymbol{g}$ & gravitational acceleration \\
$X_\alpha^\kappa$ & mass fraction of component $\kappa$ in phase $\alpha$ & $q^\kappa_\alpha$ & volume source term of $\kappa$ in $\alpha$ \\
$\varrho_{\text{mol},\alpha}$ & molar density of phase $\alpha$ & $u_\alpha$ & specific internal energy \\
$\varrho_{\alpha}$ & mass density of phase $\alpha$ & $h_\alpha$ & specific enthalpy \\
$k_{\text{r}\alpha}$ & relative permeability & $c_\text{s}$ & specific heat enthalpy \\
$\mu_\alpha$ & phase viscosity & $\lambda_\text{pm}$ & heat conductivity \\
$D_\alpha^\kappa$ & diffusivity of component $\kappa$ in phase $\alpha$ & $q^h$ & heat source term \\
$\boldsymbol{v}_\alpha$ & Darcy velocity & $\boldsymbol{v}_{a,\alpha}$ & advective velocity
\end{tabular}
\subsection{Balance Equations}
For the balance equations for multicomponent systems, it is in many
cases convenient to use a molar formulation of the continuity
equation. Considering the mass conservation for each component allows
us to drop source/sink terms for describing the mass transfer between
phases. Then, the
molar mass balance can be written as:
%
\begin{multline}
\label{A3:eqmass1}
\phi \frac{\partial (\sum_\alpha \varrho_{\text{mol}, \alpha}
x_\alpha^\kappa S_\alpha )}{\partial t}
- \sum\limits_\alpha \Div \left( \frac{k_{\text{r}
\alpha}}{\mu_\alpha} \varrho_{\text{mol}, \alpha}
x_\alpha^\kappa K (\grad p_\alpha -
\varrho_{\alpha} \boldsymbol{g}) \right) \\
%
%
- \sum\limits_\alpha \Div \left( \tau \phi S_\alpha D_\alpha^\kappa \varrho_{\text{mol},
\alpha} \grad x_\alpha^\kappa \right)
- q^\kappa = 0, \qquad \kappa \in \{\text{w,a,c}\}.
\end{multline}
The component mass balance can also be written in terms of mass fractions
by replacing molar densities by mass densities and mole by mass fractions.
To obtain a single conserved quantity in the temporal derivative, the total
concentration, representing the mass of one component per unit volume, is defined as
\begin{displaymath}
C^\kappa = \sum_\alpha \phi S_\alpha \varrho_{\text{mass},\alpha} X_\alpha^\kappa \; .
\end{displaymath}
Using this definition, the component mass balance is written as:
\begin{multline}
\label{A3:eqmass2}
\frac{\partial C^\kappa}{\partial t} =
\sum\limits_\alpha \Div \left( \frac{k_{\text{r}
\alpha}}{\mu_\alpha} \varrho_{\text{mass}, \alpha}
X_\alpha^\kappa K (\grad p_\alpha +
\varrho_{\text{mass}, \alpha} \boldsymbol{g}) \right) \\
%
%
+ \sum\limits_\alpha \Div \left( \tau \phi S_\alpha D_\alpha^\kappa \varrho_{\text{mass},
\alpha} \grad X_\alpha^\kappa \right)
+ q^\kappa = 0, \qquad \kappa \in \{\text{w,a,c}\}.
\end{multline}
In the case of non-isothermal systems, we further have to balance the
thermal energy. We assume fully reversible processes, such that entropy
is not needed as a model parameter. Furthermore, we neglect
dissipative effects and the heat transport due to molecular
diffusion. The energy balance can then be
formulated as:
%
\begin{multline}
\label{A3:eqenergmak1}
\phi \frac{\partial \left( \sum_\alpha \varrho_{\alpha}
u_\alpha S_\alpha \right)}{\partial t} + \left( 1 -
\phi \right) \frac{\partial \varrho_{\text{s}} c_{\text{s}}
T}{\partial t}
- \Div \left( \lambda_{\text{pm}} \grad T \right)
\\
- \sum\limits_\alpha \Div \left( \frac{k_{\text{r}
\alpha}}{\mu_\alpha} \varrho_{\alpha} h_\alpha
K \left( \grad p_\alpha - \varrho_{\alpha}
\boldsymbol{g} \right) \right)
- q^h \; = \; 0.
\end{multline}
In order to close the system, supplementary constraints for capillary pressure, saturations and mole
fractions are needed, \cite{A3:helmig:1997}.
According to the Gibbsian phase rule, the number of degrees of freedom
in a non-isothermal compositional multiphase system is equal to the
number of components plus one. This means we need as many independent
unknowns in the system description. The
available primary variables are, e.\ g., saturations, mole/mass
fractions, temperature, pressures, etc.
\input{box}
\section{Available models}
The following description of the available models is automatically extracted
from the Doxygen documentation.
% \textbf{TODO}: Unify notation.
\subsection{Fully-implicit models}
The fully-implicit models described in this section are using the box
scheme as described in Section \ref{box} for spatial and the implicit Euler
method as temporal discretization. The models themselves are located in
subdirectories of \texttt{ewoms/boxmodels} of the \eWoms distribution.
\subsubsection{The immiscible multi-phase model}
\input{ModelDescriptions/immisciblemodel}
\subsubsection{The miscible multi-phase NCP model}
\input{ModelDescriptions/pvsmodel}
\subsubsection{The miscible multi-phase PVS model}
\input{ModelDescriptions/pvsmodel}
\subsubsection{The miscible multi-phase flash model}
\input{ModelDescriptions/flashmodel}
\subsubsection{The Richards model}
\input{ModelDescriptions/richardsmodel}
\subsubsection{The black-oil model}
\input{ModelDescriptions/blackoilmodel}
\subsubsection{The (Navier-)Stokes model}
\input{ModelDescriptions/stokesmodel}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "ewoms-handbook"
%%% End:

View File

@ -0,0 +1,74 @@
\chapter{The Newton-Raphson method}
For the isothermal immiscible multi-phase model, the following mass
conservation equation needs to be solved:
\begin{align}
\underbrace{
\frac{\partial \phi \varrho_\alpha S_\alpha}{\partial t}
-
\text{div} \left\{
\varrho_\alpha \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\textbf{K}} \left(\text{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\textbf{g}} \right)
\right\} - q_\alpha} _
{\textbf{f}(\textbf{u})}
= 0 \; .
\end{align}
Because of the nonlinear dependencies even solving this comparatively
simple equation is a quite challenging task. However, for
finding roots of non-linear systems equations the
\textsc{Newton}-\textsc{Raphson} method can be used.
When using a fully-implicit numerical model, each time step essentially
consists of the application of the \textsc{Newton} algorithm to solve
the nonlinear system.
The idea of this algorithm is to linearize the non-linear system of
equation at a given solution, and then solving the resulting linear
system of equations. The hope is, that the solution of this linear
system is closer to the root of the non-linear system of
equations. This process is repeated until either convergence is
reached (a pre-determined accuracy is reached), or divergence of the
algorithm is detected (either by trespassing the maximum number of
iterations or by failure to linearize). This method can be formalized
as follows:
\begin{subequations}
\begin{align}
\label{NewtonGen}
\textbf{u}^{r+1} &= \textbf{u}^r + \Delta \textbf{u}^r \\
\Delta \textbf{u}^r & = - \left\{\text{grad}\,\textbf{f} (\textbf{u}^r) \right\}^{-1} \textbf{f}(\textbf{u}^r) \\
\end{align}
\end{subequations}
\noindent with
\begin{itemize}
\item $\textbf{u}$: Vector of unknowns
\item $\textbf{f}(\textbf{u}^r)$: Residual (Function of the vector of unknowns which ought to be set to $0$)
\item $\phantom{a}^r$: last iteration, $\phantom{a}^{r+1}$: current iteration,
\item $\text{grad}\,\phantom{a}$: \textsc{Jacobian} matrix of
$\textbf{f}$, i.e. matrix of the derivatives of \textbf{f} regarding
all components of $\textbf{u}$
\end{itemize}
The value of $\textbf{u}$ for which $\textbf{f}$ becomes zero is
searched for. Bringing \eqref{NewtonGen} into the form used the linear
solvers
\begin{equation}
\label{GenSysEq}
\textbf{A}\textbf{x} - \textbf{b} = 0
\end{equation}
leads to
\begin{itemize}
\item $\textbf{A} = \text{grad}\,\textbf{f} (\textbf{u}^r)$
\item $\textbf{x} = \textbf{u}^{r} - \textbf{u}^{r+1}$
\item $\textbf{b} = \textbf{f}(\textbf{u}^{r})$
\end{itemize}
Once $\textbf{u}^{r} - \textbf{u}^{r+1}$ has been calculated, \eWoms
updates the current solution in \texttt{NewtonController::update()}
and starts the next iteration if the scheme has not yet converged.
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "ewoms-handbook"
%%% End:

View File

@ -0,0 +1,41 @@
\section{Specifying Parameters}
\label{sec:inputFiles}
As already mentioned in the previous section, \eWoms allows to specify
a number of parameters at run time. A description of these parameters
can usually be obtained by passing the \texttt{--help} parameter to the
executable. The values used for these parameters are printed to the
terminal during the start-up of the simulation, e.g. the if the \texttt{lens\_immiscible}
simulation is run with the parameters \texttt{--end-time=30e3 --foo-param=123}, it will print an output similar to
\begin{lstlisting}[style=Bash]
###########
# Parameters specified at run-time
###########
EndTime="30e3"
###########
# Parameters with use compile-time fallback values
###########
AmgCoarsenTarget="5000"
...
VtkWriteSaturations="1"
VtkWriteTemperature="1"
VtkWriteViscosities="0"
###########
# Parameters unknown to the simulation
###########
FooParam="123"
\end{lstlisting}
This can be directly copy-and-pasted into a file
(e.g. \texttt{myparams.ini}). The simulation can be instructed to use
these parameters by passing the \texttt{--parameter-file=myparams.ini}
parameter the next time it is run. Of course, this file can also be
adapted.
An additional hint: Always watch out for parameters which are unknown
to the simulation, as this is \emph{very} useful for spotting typos.
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "ewoms-handbook"
%%% End:

View File

@ -0,0 +1,376 @@
\chapter{The \eWoms property system}
\label{sec:propertysystem}
This section is dedicated to the \eWoms property system. First, a high
level overview over its design and principle ideas is given, then
follows a short reference and a short self-contained example.
\section{Concepts and features of the \eWoms property system}
The \eWoms property system was designed as an attempt to mitigate the
problems of traits classes. In fact, it can be seen as a traits system
which allows easy inheritance and any acyclic dependency of parameter
definitions. Just like traits, the \eWoms property system is a compile
time mechanism, which means that there are no run-time performance
penalties associated with it. It is based on the following concepts:
\begin{description}
\item[Property:] In the context of the \eWoms property system, a
property is an arbitrary class body which may contain type
definitions, values and methods. Each property has a so-called
\textbf{property tag} which can be seen as a label with its name.
\item[Property Inheritance:] Just like normal classes, properties can
be arranged in hierarchies. In the context of the \eWoms property
system, nodes of the inheritance hierarchy are called \textbf{type
tags}.
\end{description}
It also supports \textbf{property nesting} and
\textbf{introspection}. Property nesting means that the definition of
a property can depend on the value of other properties which may be
defined for arbitrary levels of the inheritance hierarchy. The term
introspection denotes the ability to generate diagnostic messages
which can be used to find out where a certain property was defined and
how it was inherited.
\section{\eWoms property system reference}
All source files which use the \eWoms property system should include
the header file \texttt{ewoms/ \hskip-1ex{}common/
\hskip-1ex{}propertysystem.hh}. Declaration of type tags and
property tags as well as defining properties must be done inside the
namespace \texttt{Ewoms::Properties}.
\subsection*{Defining type tags}
New nodes in the type tag hierarchy can be defined using
\begin{lstlisting}[style=eWomsCode]
NEW_TYPE_TAG(NewTypeTagName, INHERITS_FROM(BaseTagName1, BaseTagName2, ...));
\end{lstlisting}
where the \texttt{INHERITS\_FROM} part is optional. To avoid
inconsistencies in the hierarchy, each type tag may be defined only
once for a program.
\vskip1ex\noindent
Example:
\begin{lstlisting}[style=eWomsCode]
namespace Ewoms {
namespace Properties {
NEW_TYPE_TAG(MyBaseTypeTag1);
NEW_TYPE_TAG(MyBaseTypeTag2);
NEW_TYPE_TAG(MyDerivedTypeTag, INHERITS_FROM(MyBaseTypeTag1, MyBaseTypeTag2));
}}
\end{lstlisting}
\subsection*{Declaring property tags}
New property tags -- i.e. labels for properties -- are declared
using
\begin{lstlisting}[style=eWomsCode]
NEW_PROP_TAG(NewPropTagName);
\end{lstlisting}
A property tag can be declared arbitrarily often, in fact it is
recommended that all properties are declared in each file where they
are used.
\vskip1ex\noindent
Example:
\begin{lstlisting}[style=eWomsCode]
namespace Ewoms {
namespace Properties {
NEW_PROP_TAG(MyPropertyTag);
}}
\end{lstlisting}
\subsection*{Defining properties}
The value of a property on a given node of the type tag hierarchy is
defined using
\begin{lstlisting}[style=eWomsCode]
SET_PROP(TypeTagName, PropertyTagName)
{
// arbitrary body of a struct
};
\end{lstlisting}
For each program, a property itself can be declared at most once,
although properties may be overwritten for derived type tags.
Also, the following convenience macros are available to define simple
properties:
\begin{lstlisting}[style=eWomsCode]
SET_TYPE_PROP(TypeTagName, PropertyTagName, type);
SET_BOOL_PROP(TypeTagName, PropertyTagName, booleanValue);
SET_INT_PROP(TypeTagName, PropertyTagName, integerValue);
SET_SCALAR_PROP(TypeTagName, PropertyTagName, floatingPointValue);
\end{lstlisting}
\vskip1ex\noindent
Example:
\begin{lstlisting}[style=eWomsCode]
namespace Ewoms {
namespace Properties {
NEW_TYPE_TAG(MyTypeTag);
NEW_PROP_TAG(MyCustomProperty);
NEW_PROP_TAG(MyType);
NEW_PROP_TAG(MyBoolValue);
NEW_PROP_TAG(MyIntValue);
NEW_PROP_TAG(MyScalarValue);
SET_PROP(MyTypeTag, MyCustomProperty)
{
static void print() { std::cout << "Hello, World!\n"; }
};
SET_TYPE_PROP(MyTypeTag, MyType, unsigned int);
SET_BOOL_PROP(MyTypeTag, MyBoolValue, true);
SET_INT_PROP(MyTypeTag, MyIntValue, 12345);
SET_SCALAR_PROP(MyTypeTag, MyScalarValue, 12345.67890);
}}
\end{lstlisting}
\subsection*{Un-setting properties}
Sometimes some inherited properties do not make sense for a certain
node in the type tag hierarchy. These properties can be explicitly
un-set using
\begin{lstlisting}[style=eWomsCode]
UNSET_PROP(TypeTagName, PropertyTagName);
\end{lstlisting}
The un-set property can not be set for the same type tag, but of
course derived type tags may set it again.
\vskip1ex\noindent
Example:
\begin{lstlisting}[style=eWomsCode]
namespace Ewoms {
namespace Properties {
NEW_TYPE_TAG(BaseTypeTag);
NEW_TYPE_TAG(DerivedTypeTag, INHERITS_FROM(BaseTypeTag));
NEW_PROP_TAG(TestProp);
SET_TYPE_PROP(BaseTypeTag, TestProp, int);
UNSET_PROP(DerivedTypeTag, TestProp);
// trying to access the 'TestProp' property for 'DerivedTypeTag'
// will trigger a compiler error!
}}
\end{lstlisting}
\subsection*{Converting type tag names to \Cplusplus types}
For the \Cplusplus compiler, type tags are like ordinary types. Both
can thus be used as template arguments. To convert a type tag name
into the corresponding type, the macro \texttt{TTAG(TypeTagName)}
ought to be used.
\subsection*{Retrieving property values}
The value of a property can be retrieved using
\begin{lstlisting}[style=eWomsCode]
GET_PROP(TypeTag, PropertyTag)
\end{lstlisting}
or using the convenience macros
\begin{lstlisting}[style=eWomsCode]
GET_PROP_TYPE(TypeTag, PropertyTag)
GET_PROP_VALUE(TypeTag, PropertyTag)
\end{lstlisting}
\vskip1ex
\noindent
The first convenience macro retrieves the type defined using
\texttt{SET\_TYPE\_PROP} and is equivalent to
\begin{lstlisting}[style=eWomsCode]
GET_PROP(TypeTag, PropertyTag)::type
\end{lstlisting}
while the second convenience macro retrieves the value of any property
defined using one of the macros \texttt{SET\_}$\{$\texttt{INT,BOOL,SCALAR}$\}$\texttt{\_PROP} and is
equivalent to
\begin{lstlisting}[style=eWomsCode]
GET_PROP(TypeTag, PropertyTag)::value
\end{lstlisting}
\vskip1ex\noindent
Example:\nolinebreak
\begin{lstlisting}[style=eWomsCode]
template <TypeTag>
class MyClass {
// retrieve the ::value attribute of the 'NumEq' property
enum { numEq = GET_PROP(TypeTag, NumEq)::value };
// retrieve the ::value attribute of the 'NumPhases' property using the convenience macro
enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) };
// retrieve the ::type attribute of the 'Scalar' property
typedef typename GET_PROP(TypeTag, Scalar)::type Scalar;
// retrieve the ::type attribute of the 'Vector' property using the convenience macro
typedef typename GET_PROP_TYPE(TypeTag, Vector) Vector;
};
\end{lstlisting}
\subsection*{Nesting property definitions}
Inside property definitions there is access to all other properties
which are defined somewhere on the type tag hierarchy. The node for
which the current property is requested is available via the keyword
\texttt{TypeTag}. Inside property class bodies this can be used to
retrieve other properties using the \texttt{GET\_PROP} macros.
\vskip1ex\noindent
Example:
\begin{lstlisting}[style=eWomsCode]
SET_PROP(MyModelTypeTag, Vector)
{
private: typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
public: typedef std::vector<Scalar> type;
};
\end{lstlisting}
\section{A self-contained example}
As a concrete example, let us consider some kinds of cars: Compact
cars, sedans, trucks, pickups, military tanks and the Hummer-H1 sports
utility vehicle. Since all these cars share some characteristics, it
makes sense to inherit those from the closest matching car type and
only specify the properties which are different. Thus, an inheritance
diagram for the car types above might look like outlined in Figure
\ref{fig:car-hierarchy}.
\begin{figure}[t]
\centering
\subfloat[]{
\includegraphics[width=.6\textwidth]{EPS/car-hierarchy.eps}
\label{fig:car-hierarchy}
}
\subfloat[]{
\includegraphics[width=.35\linewidth, keepaspectratio]{EPS/car-propertynames.eps}
\label{fig:car-propertynames}
}
\caption{\textbf{(a)}~A possible property inheritance graph for
various kinds of cars. The lower nodes inherit from higher ones;
Inherited properties from nodes on the right take precedence over the
properties defined on the left. \textbf{(b)}~Property names
which make sense for at least one of the car types of (a).}
\end{figure}
Using the \eWoms property system, this inheritance hierarchy is
defined by:
\begin{lstlisting}[name=propsyscars,style=eWomsCode]
#include <ewoms/common/propertysystem.hh>
#include <iostream>
namespace Ewoms {
namespace Properties {
NEW_TYPE_TAG(CompactCar);
NEW_TYPE_TAG(Truck);
NEW_TYPE_TAG(Tank);
NEW_TYPE_TAG(Sedan, INHERITS_FROM(CompactCar));
NEW_TYPE_TAG(Pickup, INHERITS_FROM(Sedan, Truck));
NEW_TYPE_TAG(HummerH1, INHERITS_FROM(Pickup, Tank));
\end{lstlisting}
Figure \ref{fig:car-propertynames} lists a few property names which
make sense for at least one of the nodes of Figure
\ref{fig:car-hierarchy}. These property names can be declared as
follows:
\begin{lstlisting}[name=propsyscars,style=eWomsCode]
NEW_PROP_TAG(TopSpeed); // [km/h]
NEW_PROP_TAG(NumSeats); // []
NEW_PROP_TAG(CanonCaliber); // [mm]
NEW_PROP_TAG(GasUsage); // [l/100km]
NEW_PROP_TAG(AutomaticTransmission); // true/false
NEW_PROP_TAG(Payload); // [t]
\end{lstlisting}
\noindent
So far, the inheritance hierarchy and the property names are completely
separate. What is missing is setting some values for the property
names on specific nodes of the inheritance hierarchy. Let us assume
the following:
\begin{itemize}
\item For a compact car, the top speed is the gas usage in $\unitfrac{l}{100km}$
times $30$, the number of seats is $5$ and the gas usage is
$\unitfrac[4]{l}{100km}$.
\item A truck is by law limited to $\unitfrac[100]{km}{h}$ top speed, the number
of seats is $2$, it uses $\unitfrac[18]{l}{100km}$ and has a cargo payload of
$\unit[35]{t}$.
\item A tank exhibits a top speed of $\unitfrac[60]{km}{h}$, uses $\unitfrac[65]{l}{100km}$
and features a $\unit[120]{mm}$ diameter canon
\item A sedan has a gas usage of $\unitfrac[7]{l}{100km}$, as well as an automatic
transmission, in every other aspect it is like a compact car.
\item A pick-up truck has a top speed of $\unitfrac[120]{km}{h}$ and a payload of
$\unit[5]{t}$. In every other aspect it is like a sedan or a truck but if in
doubt, it is more like a truck.
\item The Hummer-H1 SUV exhibits the same top speed as a pick-up
truck. In all other aspects it is similar to a pickup and a tank,
but, if in doubt, more like a tank.
\end{itemize}
\noindent
Using the \eWoms property system, these assumptions are formulated
using
\begin{lstlisting}[name=propsyscars,style=eWomsCode]
SET_INT_PROP(CompactCar, TopSpeed, GET_PROP_VALUE(TypeTag, GasUsage) * 30);
SET_INT_PROP(CompactCar, NumSeats, 5);
SET_INT_PROP(CompactCar, GasUsage, 4);
SET_INT_PROP(Truck, TopSpeed, 100);
SET_INT_PROP(Truck, NumSeats, 2);
SET_INT_PROP(Truck, GasUsage, 18);
SET_INT_PROP(Truck, Payload, 35);
SET_INT_PROP(Tank, TopSpeed, 60);
SET_INT_PROP(Tank, GasUsage, 65);
SET_INT_PROP(Tank, CanonCaliber, 120);
SET_INT_PROP(Sedan, GasUsage, 7);
SET_BOOL_PROP(Sedan, AutomaticTransmission, true);
SET_INT_PROP(Pickup, TopSpeed, 120);
SET_INT_PROP(Pickup, Payload, 5);
SET_INT_PROP(HummerH1, TopSpeed, GET_PROP_VALUE(TTAG(Pickup), TopSpeed));
\end{lstlisting}
\noindent
At this point, the Hummer-H1 has a $\unit[120]{mm}$ canon which it inherited
from its military ancestor. It can be removed by
\begin{lstlisting}[name=propsyscars,style=eWomsCode]
UNSET_PROP(HummerH1, CanonCaliber);
}} // close namespaces
\end{lstlisting}
\noindent
Now property values can be retrieved and some diagnostic messages can
be generated. For example
\begin{lstlisting}[name=propsyscars,style=eWomsCode]
int main()
{
std::cout << "top speed of sedan: " << GET_PROP_VALUE(TTAG(Sedan), TopSpeed) << "\n";
std::cout << "top speed of truck: " << GET_PROP_VALUE(TTAG(Truck), TopSpeed) << "\n";
std::cout << PROP_DIAGNOSTIC(TTAG(Sedan), TopSpeed);
std::cout << PROP_DIAGNOSTIC(TTAG(HummerH1), CanonCaliber);
Ewoms::Properties::print<TTAG(Sedan)>();
}
\end{lstlisting}
will yield the following output:
\begin{lstlisting}[style=eWomsCode]
top speed of sedan: 210
top speed of truck: 100
Properties for Sedan:
bool AutomaticTransmission = 'true' defined at test_propertysystem.cc:68
int GasUsage = '7' defined at test_propertysystem.cc:67
Inherited from CompactCar:
int NumSeats = '5' defined at test_propertysystem.cc:55
int TopSpeed = '::Ewoms::Properties::GetProperty<TypeTag, ::Ewoms::Properties::PTag::GasUsage>::p::value * 30' defined at test_propertysystem.cc:54
\end{lstlisting}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "ewoms-handbook"
%%% End:

View File

@ -0,0 +1,73 @@
\section{Installation of \eWoms} \label{quick-install}
This section describes a way of installing \eWoms that works in most
cases, but depending on your operating system of choice, \Cplusplus
compiler and features which you need, some tweaks are possibly
required. As a pre-requisite it is assumed, that you are using a
recent Linux distribution that has the appropriate development
packages (\Cplusplus compiler, autoconf, automake, libtool and
pkg-config amongst possibly others) installed, but that you did not
install \Dune via distribution provided packages. If you need more
information, or if you have \Dune already installed, please have a
look at the detailed installation instructions in Section
\ref{install}.
\subsection{Retrieving the code}
You can retrieve all required \Dune modules by either downloading and
unpacking the tarballs for the \Dune-2.2 release followed by
downloading and unpacking the tarball for the \eWoms 2.2 release, or
by retrieving the code directly from their respective source-code
repositories. If you decide to use the first method, make sure to
unpack all tarballs into the same directory; if you prefer the second
method, make sure that you have the \texttt{git} version control
system with the SVN plug-in installed on your computer and enter the
following code snippet into a terminal:
\begin{lstlisting}[style=Bash]
cd $YOUR_DUNE_ROOT_DIRECTORY
for DUNE_MODULE in common geometry grid istl localfunctions; do \
git svn clone https://svn.dune-project.org/svn/dune-$DUNE_MODULE/branches/release-2.2 $DUNE_MODULE \
done
git clone --branch "release-2.2" git://github.com/OPM/ewoms.git
\end{lstlisting}
%$
\subsection{Building \Dune and \eWoms}
\label{buildIt}
\eWoms is a \Dune module and is recommended to build it using the \Dune
build system~\cite{DUNE-BS}. To simplify things, \eWoms ships with a
few option files for \Dune's build script, \texttt{dunecontrol}. If
you are using \eWoms the first time, we recommend to use the options
optimized for the debugging experience, \texttt{debug.opts}:
\begin{lstlisting}[style=Bash]
cd $YOUR_DUNE_ROOT_DIRECTORY
./dune-common/bin/dunecontrol --opts=ewoms/debug.opts all
\end{lstlisting}
%$
Once you have finished developing and testing your own code on
small-scale problems, re-compile everything with compiler
optimizations enabled before a production run in order to speed things
up by a factor of approximately 10:
\begin{lstlisting}[style=Bash]
cd $YOUR_DUNE_ROOT_DIRECTORY
./dune-common/bin/dunecontrol --opts=ewoms/optim.opts all
\end{lstlisting}
%$
Sometimes it is necessary to have additional options which might be
specific to the operating system of your choice, or if you have
special requirements. For this reason, the option files mentioned
above should be rather understood as a starting point for your own
option files than as something fixed; feel free to copy and modify
them. To avoid confusion, it is helpful to rename your
customized option files, though.
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "ewoms-handbook"
%%% End:

View File

@ -0,0 +1,87 @@
\section[Quick start guide]{Compiling and running a sample application}
\label{quick-start-guide}
The previous section showed how to install and compile \eWoms. This
chapter gives you a very brief introduction how to run a first test
application and how to visualize the output files it produces. Only the
rough steps will be described here; More detailed explanations can be
found in the tutorials in the following chapter.
\begin{enumerate}
\item Go to the directory \texttt{test}. There, various test
application folders can be found. Let us consider as example
the one for the fully-implicit models, \texttt{boxmodels}:
\item Enter the folder \texttt{boxmodels}.
\item By default, the \texttt{dunecontrol} command only compiles the
parts of \Dune modules that are necessary to build modules depending
on the given module. For \eWoms, \texttt{dunecontrol} does not build
anything by default, because \eWoms only provides \Cplusplus
template classes but no libraries that need compilation. To compile
the test simulation for the "lens" problem which uses the fully-implicit
model that assumes immisciblility, enter
\begin{lstlisting}[style=Bash]
make lens_immiscible
\end{lstlisting}
You may also compile all available tests which use the box scheme by entering
\begin{lstlisting}[style=Bash]
make check
\end{lstlisting}
This takes quite some time, but if you have a multi-core processor
with \$N cores, you can considerably speed up compilation by using all
of available cores by using
\begin{lstlisting}[style=Bash]
make -j $N check
\end{lstlisting}
%$
\item If everything was compiled correctly, there should be an
executable called '\texttt{lens{\_}immiscible}'. To run the simulation,
simply execute it, i.e. enter
\begin{lstlisting}[style=Bash]
./lens_immiscible
\end{lstlisting}
You may also want to change some parameters from the command line. For
example, if you want to change the time up to which the problem is
simulated to $30.000$ seconds, use
\begin{lstlisting}[style=Bash]
./lens_immiscible --end-time=30e3
\end{lstlisting}
You can also get a list of parameters recognized by the
simulation together with a brief description, by running
\begin{lstlisting}[style=Bash]
./lens_immiscible --help
\end{lstlisting}
\item After this, the simulation should start and produce some output
on the terminal. It is possible to interrupt it at any time by
pressing \texttt{<Ctrl>+<C>}.
\item The actual output files produced by the simulation are a series
of \texttt{.vtu} files and a \texttt{.pvd} file. Each \texttt{.vtu}
file contains "visualization ready" data for a single time step,
while the \texttt{.pvd} file "stitches" these files together into a
coherent data set. For example, the \texttt{.pvd} holds the
simulation time at which a given time step was produced, that can
later be used for visualization.
\item You can now display the result of the simulation using the
visualization tool ParaView (or, if you prefer, VisIt). Just type
\texttt{paraview} in the console and open the \texttt{.pvd} file. On
the left hand side, you should now be able to click the green
``Apply'' button. Once you have done this, the visualization of the
simulation result appears on the screen and you can click the
``play'' button in the toolbar to view display its evolution over
time. Also note that you can choose the visualized quantity
in the toolbar. For the lens problem, the most interesting quantities
are probably the saturations.
\item Play a bit around to make your self familiar with the
visualization tool of your choice as you will be using it a lot.
\end{enumerate}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "ewoms-handbook"
%%% End:

124
doc/handbook/structure.tex Normal file
View File

@ -0,0 +1,124 @@
\chapter{Directory structure}
We briefly describe the directory structure of \eWoms in terms
of subdirectories, source files, and tests. For more details,
the Doxygen documentation should be considered.
\eWoms comes in form of a DUNE module \texttt{ewoms}.
It has a similar structure as other DUNE modules like \texttt{dune-grid}.
The following subdirectories are within the module's root directory,
from now on assumed to be \texttt{/}:
\begin{itemize}
\item \texttt{CMake}: the configuration options
for building \eWoms using CMake. See the file \texttt{INSTALL.cmake} in
the root directory of the \eWoms distribution for details. Of course,
it is also possible to use the DUNE buildsystem just like for the other
DUNE modules.
\item \texttt{doc}: contains the Doxygen documentation in \texttt{doxygen},
this handbook in \texttt{handbook}, and the \eWoms logo in various formats in
\texttt{logo}. The html documentation produced by Doxygen can be accessed as usual,
namely, by opening \texttt{doc/doxygen/html/index.html} with a web browser.
\item \texttt{ewoms}: the \eWoms source files. See Section \ref{sec:ewoms} for details.
\item \texttt{test}: tests for each numerical model and the property system.
See Section \ref{sec:test} for details.
\item \texttt{tutorial}: contains the tutorials described in Chapter \ref{chp:tutorial}.
\end{itemize}
\subsection{The \texttt{ewoms} directory}\label{sec:ewoms}
The directory \texttt{ewoms} contains the \eWoms source files. It consists of the following subdirectories (see Figure \ref{fig:ewoms-structure}):
\begin{itemize}
\item \texttt{boxmodels}: The fully implicit vertex-centered finite
volume (box) method. This directory features the following
sub-directories
\begin{itemize}
\item \texttt{common}: The infrastructural code shared by all box
models; For example it contains the file
\texttt{boxfvelementgeometry.hh} which is used by the box scheme to
construct the dual grid out of the primal one.
\item \texttt{modules}: This directory features parts which can be
re-used by multiple models, like a generic plug-in for the energy
equation, models for determining the filter velocity, or plugins
describing molecular diffusion.
\item Each of the other subdirectories contains
a physical numerical model which uses the box discretization.
\end{itemize}
\item \texttt{common}: General stuff like the \eWoms property system
and classes for managing time which are shared by the fully-implicit
and the semi-implicit models. For example it features the file
\texttt{start.hh} which provides the default way for starting a
simulation.
\item \texttt{io}: Additional classes that provide in-/output routines
like writing and reading restart files (often called 'checkpoint'
files) and for writing a series of VTK files.
\item \texttt{material}: Everything related to material parameters and
constitutive equations. For example, the properties of a pure
chemical substance (e.g. water) or pseudo substance (e.g. air) can
be found in the subdirectory \texttt{components} with the base class
\texttt{components/component.hh}. Fluid systems are located in the
sub-folder \texttt{fluidsystems}, while capillary pressure/relative
permeability laws are located in the sub-folder
\texttt{fluidmatrixinteractions}. Furthermore, the classes computing
binary coefficients like the Henry coefficient or binary diffusion
coefficients are held by the sub-folder \texttt{binarycoefficients}.
\item \texttt{nonlinear}: This folder contains an implementation of
the Newton-Raphson method for solving non-linear systems of
equations.
\item \texttt{linear}: This folder features code which is required to
parallelize the linear solvers, as well as back-ends for these
solvers. For example it contains classes to calculate an overlap
given the distributed matrix of the linear system, and provides
classes which use this overlap to provide overlapping matrices,
vectors, linear operators and scalar products.
\item \texttt{istl}: This folder contains a copy of slightly modified
linear solvers from the ISTL \Dune module. The reason why they where
copied is to provide linear solvers with better performance and
stability without being held back by the \Dune developers.
\item \texttt{parallel}: Contains some helper classes useful for
programming MPI parallel code. For example this folder contains a
simple MPI buffer class, and various commonly used \Dune
data-handles.
\end{itemize}
\subsection{The directory \texttt{test}}\label{sec:test}
The directory \texttt{test} contains at least one test/example for
each numerical model and for each important aspect of the common
\eWoms infrastructure. The directory \texttt{common} contains a test
for the property system. The sub-directory \texttt{implicit}
contains test applications for the fully-implicit models (where each
test is named according to the scheme \texttt{PROBLEMNAME\_MODDEL}).
Each subdirectory contains one or more program
files \texttt{*.cc} which contain the main function for the
test. Moreover, the problem definitions can be found in the
\texttt{*problem.hh} files. Simply executing the tests should either
run the full test or give a list of required command line
arguments. After test execution, VTK output files are generated by
most tests. For more detailed descriptions of the tests, the problem
definitions and their corresponding Doxygen documentation should be
considered.
\begin{landscape}
\begin{figure}[hbt]
\centering
\includegraphics[width=\linewidth, keepaspectratio]{EPS/ewoms_structure.eps}
\caption{
\label{fig:ewoms-structure}
Structure \texttt{ewoms} sub-directory of the \eWoms source tree.
}
\end{figure}
\end{landscape}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "ewoms-handbook"
%%% End:

View File

@ -0,0 +1,3 @@
\section[New model]{How to implement a new model}
TODO: describe how to impelment a new model

30
doc/handbook/tutorial.tex Normal file
View File

@ -0,0 +1,30 @@
\chapter[Tutorial]{Tutorial}\label{chp:tutorial}
\eWoms provides two sorts of models: Models which use a fully-implicit
discretization in space and time and models that use a
semi-implicit space and an explicit time discretization.
Fully-implicit models as implemented by \eWoms describe the
conservation quantities of a flow system as a system of strongly
coupled partial differential equations which is directly using a
non-linear solver. Physically, these conservation quantities are mass,
momentum and energy; Although the momentum is usually not explicitly
conserved in the context of flow models for porous media.
In section \ref{box} a short introduction to the vertex centered
finite volume scheme (VCFV or box method) used by \eWoms as the
primary spatial discretization is given.
The purpose of this chapter is to introduce how flow problems can be
solved in \eWoms. Being a simple but representative case, an
isothermal two-phase problem (i.e. two fluid phases, one solid phase)
will be considered. The source code of these tutorials is shipped with
the \eWoms source package and can be found in the \texttt{tutorial}
directory.
\input{tutorial1}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "ewoms-handbook"
%%% End:

548
doc/handbook/tutorial1.tex Normal file
View File

@ -0,0 +1,548 @@
\section{Upfront considerations}
\label{tutorial1}
The process of setting up a problem using \eWoms can be roughly
divided into three parts:
\begin{enumerate}
\item A suitable model has to be chosen.
\item The geometry of the problem has to be defined and the suitable
grid has to be created.
\item Boundary and initial conditions and material properties have to
be specified.
\end{enumerate}
The physical set-up of the flow problem being solved in this tutorial
is illustrated in Figure \ref{tutorial1:problemfigure}: It
consists of a rectangular domain with no-flow boundary conditions on
the top and on the bottom of the domain, which is initially fully
saturated by a light oil. Water infiltrates from the left side and
replaces the oil. The effect of gravity is neglected.
\begin{figure}[ht]
\psfrag{x}{x}
\psfrag{y}{y}
\psfrag{no flow}{no flow}
\psfrag{water}{\textbf{water}}
\psfrag{oil}{\textcolor{white}{\textbf{oil}}}
\psfrag{p_w = 2 x 10^5 [Pa]}{$p_w = 2 \times 10^5$ [Pa]}
\psfrag{p_w_initial = 2 x 10^5 [Pa]}{\textcolor{white}{\textbf{$\mathbf{p_{w_{initial}} = 2 \times 10^5}$ [Pa]}}}
\psfrag{S_n = 0}{$S_n = 0$}
\psfrag{S_n_initial = 0}{\textcolor{white}{$\mathbf{S_{n_{initial}} = 1}$}}
\psfrag{q_w = 0 [kg/m^2s]}{$q_w = 0$ $\left[\frac{\textnormal{kg}}{\textnormal{m}^2 \textnormal{s}}\right]$}
\psfrag{q_n = -3 x 10^-4 [kg/m^2s]}{$q_n = 3 \times 10^{-2}$ $\left[\frac{\textnormal{kg}}{\textnormal{m}^2 \textnormal{s}}\right]$}
\centering
\includegraphics[width=0.9\linewidth,keepaspectratio]{EPS/tutorial-problemconfiguration}
\caption{Geometry of the tutorial problem with initial and boundary conditions.}\label{tutorial1:problemfigure}
\end{figure}
The solved equations are the mass balances of water and oil:
\begin{align}
\label{massbalancewater}
\frac {\partial (\phi \, S_{w}\, \varrho_{w})}{\partial t}
-
\nabla \cdot \left( \varrho_{w} \, \frac{k_{rw}}{\mu_{w}} \, \mathbf{K}\;\nabla p_w \right)
-
q_w
& =
0 \\
\label{massbalanceoil}
\frac {\partial (\phi \, S_{o}\, \varrho_{o})}{\partial t}
-
\nabla \cdot \left( \varrho_{o} \, \frac{k_{ro}}{\mu_{o}} \, \mathbf{K}\;\nabla p_o \right)
-
q_o
& =
0
\end{align}
\subsection{The main source file}
Listing \ref{tutorial1:mainfile} shows the main file
\texttt{tutorial/tutorial1.cc} for the tutorial problem using
a fully-implicit model that assumes immiscibility. This file has to be
compiled and executed in order to solve the problem described above.
\begin{lst}[File tutorial/tutorial1.cc]\label{tutorial1:mainfile} \mbox{}
\lstinputlisting[style=eWomsCode, numbersep=5pt, firstline=27, firstnumber=27]{../../tutorial/tutorial1.cc}
\end{lst}
In \eWoms, this file is usually quite short, as most of the work for
setting up the simulation is done by the generic startup routine
\texttt{Ewoms::start()}. The tasks left for the main source file are:
\begin{itemize}
\item Inclusion of the necessary header files from line
\ref{tutorial1:include-begin} to line
\ref{tutorial1:include-end}.
\item Specifying the type tag of the problem which is going to be
simulated at line \ref{tutorial1:set-type-tag}.
\item Starting the simulation using default \eWoms startup routine
\texttt{Ewoms::start()} on line \ref{tutorial1:call-start}.
\end{itemize}
The default \eWoms startup routine parses the command line arguments,
optionally reads a file which may specify further parameters, creates
the grid which represents the spatial domain, and then starts the
actual simulation. Parameters for the simulation, can be either
specified using command line arguments of the form
(\texttt{--parameter-name=value}), or in the file specified by the
\texttt{--parameter-file="file\_name"} argument. The list of all
parameters used by a simulation can be obtained by passing
\texttt{--help} to the executable on the command line.
\subsection{The problem file}
\begin{lst}[File tutorial/tutorial1problem.hh] \label{tutorial1:problemfile}\mbox{}
\lstinputlisting[style=eWomsCode, numbersep=5pt, firstline=28, firstnumber=28]{../../tutorial/tutorial1problem.hh}
\end{lst}
For using \eWoms, the central file is the \emph{problem file} as
shown in listing~\ref{tutorial1:problemfile}. This file is responsible
for specifying the physical setup of the problem which is to be
simulated. In this context, all problems first need to set up the
relevant properties for the \eWoms property system:
\begin{itemize}
\item First, a new type tag is created for the problem on line
\ref{tutorial1:create-type-tag}. In this case, the new type
tag inherits all properties from the \texttt{ImmiscibleTwoPhaseModel}
type tag, which means that for this problem the immiscible model
for two fluid phases is chosen as discretization scheme.
\item Next, the spatial discretization which ought to be used is
selected on line~\ref{tutorial1:include-discretization}. In this
case, the vertex-centered finite volume (VCFV) method is chosen.
\item On line \ref{tutorial1:set-problem}, the problem class is
specified for the new type tag, while the kind of grid that is to be
used is defined in line \ref{tutorial1:set-grid} -- in this case
it is \texttt{Dune::YaspGrid}.
\item Since \Dune does not provide a uniform mechanism to create or
load grids, \eWoms features the concept of grid managers. In this
case, the generic \texttt{CubeGridManager} is used. This grid
manager constructs a structured rectangular grid with a specified
size and resolution. For this grid manager, the physical domain of
the grid is specified via the run-time parameters
\texttt{DomainSizeX} and \texttt{DomainSizeY} and its resolution by
\texttt{CellsX} and \texttt{CellsY}. These parameters can be
specified via the command-line or in a parameter file, but the
problem file must define default values for them. Defining these
defaults is done on lines \ref{tutorial1:grid-default-params-begin}
to \ref{tutorial1:default-params-end}.
\end{itemize}
Next, an appropriate fluid system -- which specifies the thermodynamic
relations of the fluid phases -- has to be chosen. By default, the
immiscible model for two fluid phases uses
\texttt{\justifyNoHyphen{}Ewoms::Fluid\-Systems::TwoPImmiscible}. This
fluid system simplifies things considerably by assuming immiscibility
of the phases, but it requires to explicitly specify the fluids of the
wetting and non-wetting phases. In this case, liquid water based on
simple relations is selected as the wetting phase on line
\ref{tutorial1:wettingPhase} and a light liquid oil is chosen as the
non-wetting phase on line \ref{tutorial1:nonwettingPhase}. The next
property, which is set on line \ref{tutorial1:gravity}, tells the
model not to use gravity. This is then followed by the specification
default values for parameters specifying the temporal and spatial
simulation domain from line \ref{tutorial1:default-params-begin} to
line \ref{tutorial1:default-params-end}. The values of those can be
overwritten at run-time if desired.
Following the property definitions, is the problem class which
specifies the variable parameters of the physical set-up to be
simulated. Such parameters are, for example, boundary and initial
conditions, source terms and spatially dependent quantities like
temperature, porosity, intrinsic permeability and the parameters
required by the capillary pressure/relative permeability law within
the domain. Since there are quite a few methods necessary to fully
specify a problem, and it is often possible to specify meaningful
defaults, it is strongly recomended to derive the problem from the
class specified by the \texttt{BaseProblem} property as done on line
\ref{tutorial1:def-problem}\footnote{Technically, deriving the problem
from the \texttt{BaseProblem} is not required if it implements all
necessary methods. Do not complain if things explode in this case,
though.}.
For the isothermal multi-phase porous media model which assumes
immiscibility, the problem class provided by the user must implement
at least the following methods:
\begin{itemize}
\item \texttt{initial()} for specifying the initial condition within
the domain,
\item \texttt{source()} which defines the source term for each conservation quantity,
\item \texttt{boundary()} for the conditions at the spatial domain's
boundary,
\item \texttt{temperature()} which provides the temperature within the
spatial domain. Note, that if energy is conserved, this method is
not necessary. Instead, energy fluxes must be specified by the
\texttt{boundary()} and \texttt{source()} methods and an initial
temperature needs to be defined by the \texttt{initial()} method in
this case.
\item \texttt{intrinsicPermeability()} for returning the intrinsic
permeability matrix $\mathbf{K}$ in $[m^2]$ at a given location.
\item \texttt{porosity()} which specifies the ratio of pore space to
total volume of the medium at a given location.
\item \texttt{materialLawParams()} which defines the parameters for
the capillary pressure and relative permeability relations at a
given location.
\end{itemize}
All of these methods take a single template argument,
\texttt{Context}, and the three function arguments \texttt{context},
\texttt{spaceIdx} and \texttt{timeIdx}. Together, these form the
so-called \emph{execution context}. The execution context can be
thought of as a collection of all available information for a given
method. Thus, execution contexts a way to abstract away the
differences of discretization schemes. The following methods are
provided by all \texttt{context} objects:
\begin{itemize}
\item \texttt{pos(spaceIdx, timeIdx)}: This method returns the
relevant position of the execution context within the spatial
domain.
\item \texttt{globalSpaceIndex(spaceIdx, timeIdx)}: Returns a global
index for the spatial degree of freedom which is associated to the
execution context. This index can be used to store spatially
dependent information in an array.
\item \texttt{element()}: Returns the \Dune grid element to which the
execution context applies.
\item \texttt{gridView()}: Returns the \Dune grid view of which the
element is part of.
\item \texttt{problem()}: Returns the \eWoms object which describes
the physical problem to be solved.
\item \texttt{model()}: Returns the \eWoms model which is used to simulate
the physical problem.
\end{itemize}
The execution contexts for the \texttt{source} and \texttt{boundary}
methods always provide the following methods in addition:
\begin{itemize}
\item \texttt{volVars(spaceIdx, timeIdx)}: The secondary variables
used by the model relevant for the execution context. These are
useful to specify solution dependent source and boundary terms.
\item \texttt{primaryVars(spaceIdx, timeIdx)}: The vector of primary
variables to which the model solves for.
\end{itemize}
Finally, the execution context for the \texttt{boundary} method
provides the methods \texttt{boundarySegmentArea(spaceIdx, timeIdx)},
and \texttt{normal(spaceIdx, timeIdx)}, which return the area of the
boundary segment and outer unit normal of the boundary segment.
When specifying the boundary conditions in the problem class, a small
safeguard value \texttt{eps\_} should usually be added when comparing
spatial coordinates. For the problem considered here, the left
boundary might not be detected if checking whether the first
coordinate of the global position is equal to zero, but it is detected
reliably by testing whether it is smaller than an
$\epsilon$-value. Also, the \texttt{bboxMax()} (``\textbf{max}imum
coordinate of the grid's \textbf{b}ounding \textbf{box}'') method is
used here to determine the extend of the physical domain. It returns a
vector with the maximum values on each axis of the grid. This method
and the analogous \texttt{bboxMin()} method are provided by the
problem's base class.
In addition to these methods, there might be some additional
model-specific methods.
\subsection{Defining fluid properties}
\label{tutorial1:description-fluid-class}
The \eWoms distribution includes representations of some common
substances which can be used out of the box. The properties of pure
substances (such as nitrogen, water, or the pseudo-component air) are
provided by header files located in the folder
\texttt{ewoms/material/components}.
When two or more substances are considered, interactions between these
become relevant and the properties of these mixtures of substances --
e.g. composition, density or enthalpy -- are required. In \eWoms, such
interactions are defined by {\em fluid systems}, which are located in
\texttt{ewoms/material/fluidsystems}. A more thorough overview of the
\eWoms fluid framework can be found in
chapter~\ref{sec:fluidframework}.
\subsection{Exercises}
\label{tutorial1:exercises}
The following exercises will give you the opportunity to learn how you
can change soil parameters, boundary conditions, run-time parameters
and fluid properties in \eWoms.
\subsubsection{Exercise 1}
\renewcommand{\labelenumi}{\alph{enumi})}
For Exercise 1 you have to modify the tutorial files only sightly, or
even not at all.
\begin{enumerate}
\item \textbf{Running the Program} \\
To get an impression what the results should look like, you can
first run the original version of the tutorial problem by entering
the directory into which you installed \eWoms, followed typing
\texttt{make tutorial1 \&\& ./bin/tutorial1}. Note, that the
time-step size is automatically adapted during the simulation. For
visualizing the results using the program \texttt{paraview}, please
refer to section \ref{quick-start-guide}.
\item \textbf{Changing the Model Domain} \\
Change the size of the model domain so that you get a rectangle with
edge lengths of $\text{x} = \unit[400]{m}$ and $\text{y} =
\unit[500]{m}$ and with discretization lengths of $\Delta \text{x} =
\unit[20]{m}$ and $\Delta \text{y} = \unit[20]{m}$. For this, you can
either change the properties defined between lines
\ref{tutorial1:default-params-begin} and
\ref{tutorial1:default-params-end}, or you may pass them as
command line parameters to the simulation when you run it.
If you chose to change the problem file, re-compile the simulation
by typing \texttt{make tutorial1} in the toplevel directory of your
\eWoms build directory. Note, that you do not have to recompile the
program if you use command line parameters. In both cases, don't
forget run the simulation before re-inspecting the results using
\texttt{paraview}.
\item \textbf{Boundary Conditions} \\
Change the boundary conditions in the problem file
\texttt{tutorial1problem.hh} so that water enters from the
bottom and oil is extracted from the top boundary. The right and the
left boundary should be closed for both, water and oil.
Note that in \eWoms, flux boundary conditions are specified as
fluxes of the conserved quantities into the direction of the outer
normal per area. This means a mass flux into the domain is negative,
a flux out of the domain is always positive. Re-compile the
simulation by typing \texttt{make tutorial1} and re-run it
as explained above.
\item \textbf{Changing the Spatial Discretization} \\
Change the spatial discretization used for this problem from the
vertex-centered finite element method (VCFV) to the element-centered
one (ECFV). For this, you need to change the file included on
line~\ref{tutorial1:include-discretization} and the definition of
the splice for the spatial discretization on
line~\ref{tutorial1:set-spatial-discretization}.
\item \textbf{Changing the Shape of the Discrete Elements} \\
In order to complete this exercise you need a \Dune grid manager
that is capable of handling simplex grids. By default, \Dune does
not include such a grid manager in its core modules, but the freely
available \texttt{ALUGrid}~\cite{ALUGRID-HP} can be used. If you do
not want to go through the trouble of installing this grid manager,
please skip this exercise.
Change the grid manager used by the problem to
\texttt{SimplexGridManager<TypeTag>} and the type of the grid to
\texttt{Dune::ALUSimplexGrid<2, 2>}. The grid manager is specified
on line \ref{tutorial1:set-grid-manager}, while the type of the
\Dune grid manager is set on line
\ref{tutorial1:set-grid}. You also need to change the include
statement of the grid manager from \texttt{cubegridmanager.hh} to
\texttt{simplexgridmanager.hh} on line
\ref{tutorial1:include-grid-manager} and the one for the grid
manager from \texttt{dune/grid/yaspgrid.hh} to
\texttt{dune/grid/alugrid.hh} on line \ref{tutorial1:include-grid-manager}.
The resulting grid can be examined by re-compiling and starting the
simulation, loading the result into \texttt{paraview}, and selecting
\texttt{Surface with Edges} instead of the default visualization
mode \texttt{Surface}.
\item \textbf{Changing Fluids} \\
In this exercise you will change the fluids used: Use DNAPL instead
of LNAPL and Brine instead of Water. This can be done by the
following steps:
\begin{enumerate}
\item Brine: Brine is thermodynamically very similar to pure water but
also includes a fixed amount of salt in the liquid phase. Hence,
the class \texttt{Ewoms::Brine} calls back to a class which
represents pure water. (This can be, for example
\texttt{Ewoms::H2O}, or \texttt{Ewoms::SimpleH2O}.) The class which
represents pure water is passed to \texttt{Ewoms::Brine} as the
second template argument after the data type for scalar values,
i.e. the full definition of the brine component is
\texttt{Ewoms::Brine<Scalar, Ewoms::H2O<Scalar> >}. The file which
defines the brine component is located in the folder
\texttt{ewoms/material/components/}. Include this file and select
use the brine component as the wetting phase.
\item DNAPL: Now let us use a component that represents an oil that
is heavier than water (in environmental engineering this class of
substances is often called \textbf{d}ense
\textbf{n}on-\textbf{a}queous \textbf{p}hase \textbf{l}iquid
(DNAPL)) which is also located in the folder
\texttt{ewoms/material/components/}. Include the correct file and
use the DNAPL component as the non-wetting phase.
\end{enumerate}
If you want to take a closer look on how the fluid classes are defined
and which substances are available in the \eWoms distribution, feel
free to browse through the files in the directory
\texttt{ewoms/material/components} and read
chapter~\ref{sec:fluidframework}.
\item \textbf{Use a Full-Fledged Fluid System} \\
In \eWoms, the canonical way to describe fluid mixtures is via
\emph{fluid systems}\footnote{For a thorough introduction into
fluid systems and the concepts related to it, see chapter
\ref{sec:fluidframework}}. In order to include a fluid system,
you first have to comment out lines
\ref{tutorial1:2p-system-start}
to \ref{tutorial1:2p-system-end} in the problem file.\\
Now include the file
\texttt{ewoms/material/fluidsystems/h2oairfluidsystem.hh}, and
instruct the model to use this fluid system by setting
the \texttt{FluidSystem} property via:\\
\begin{lstlisting}[style=eWomsCode]
SET_TYPE_PROP(Tutorial1Problem,
FluidSystem,
Ewoms::FluidSystems::H2OAir<typename GET_PROP_TYPE(TypeTag, Scalar)>)
\end{lstlisting}
However, this is a rather complicated fluid system which considers all
fluid phases as a mixture of the components and also uses tabulated
components that need to be filled with values (i.e. some components
use tables to speed up expensive computations). The initialization of
the fluid system is normally done in the constructor of the problem by
calling \texttt{FluidSystem::init();}.
As water flow replacing a gas is much faster, simulate the problem
only until $2.000$ seconds is reached and start with a time step of
$1$ second.
Now, revert the changes made in this part of the exercise, as we will
continue to use immiscible phases from here on and hence do not need a
complex fluid system.
\item \textbf{Changing Constitutive Relations} \\
Instead of using a regularized Brooks-Corey law for the relative
permeability and for the capillary pressure saturation relationship,
use an linear material law which does not consider residual
saturation. The new material law should exhibit an entry pressure of
$p_e = 0.0\;\text{Pa}$ and maximal capillary pressure of
$p_{c_{max}} = 2000.0\;\text{Pa}$. To do that, you have to change
the material law property on line
\ref{tutorial1:eff2abs} as follows:
\begin{itemize}
\item First, switch to the linear material law. This can be achieved
by replacing \texttt{RegularizedBrooksCorey} in the private section
of the property definition by \texttt{LinearMaterial} and rename
\texttt{RawMaterialLaw} to \texttt{TwoPMaterialLaw}. Also remove the
line which contains the \texttt{EffToAbsLaw} typedef.
\item Then, adapt the necessary parameters of the linear law and the
respective \texttt{set}-functions can be found in the file
\texttt{ewoms/material/fluidmatrixinteractions/2p/linearmaterialparams.hh}.\\
Call the \texttt{set}-functions from the constructor of the problem.
\item Finally, re-compile and re-run the simulation. In order to
successfully compile the simulation, you also have to include the
header file which contains the linear material law. This header is
called \texttt{linearmaterial.hh} and is located in the same
directory as the header for the regularized Brooks-Corey law,
\texttt{regularizedbrookscorey.hh}.
\end{itemize}
\item \textbf{Heterogeneities} \\
Set up a model domain with the soil properties given in Figure
\ref{tutorial1:exercise1_d}. Adjust the boundary conditions
so that water is flowing from the left to the right of the domain again.
\begin{figure}[ht]
\psfrag{K1 =}{$\mathbf{K} = 10^{-8}\;\text{m}^2$}
\psfrag{phi1 =}{$\phi = 0.15$}
\psfrag{K2 =}{\textcolor{white}{$\mathbf{K} = 10^{-9}\;\text{m}^2$}}
\psfrag{phi2 =}{\textcolor{white}{$\phi = 0.3$}}
\psfrag{600 m}{$600 \;\text{m}$}
\psfrag{300 m}{$300 \;\text{m}$}
\centering
\includegraphics[width=0.5\linewidth,keepaspectratio]{EPS/exercise1_c.eps}
\caption{Exercise 1f: Set-up of a model domain with a heterogeneity. $\Delta x = 20 \;\text{m}$ $\Delta y = 20\;\text{m}$.}\label{tutorial1:exercise1_d}
\end{figure}
You can use the fluids of exercise 1b).
\textbf{Hint:} The relevant position in the domain can be obtained using
\texttt{const auto \&pos=context.pos(spaceIdx, timeIdx);}
When does the front cross the material border? In paraview, the
animation view (\emph{View} $\rightarrow$ \textit{Animation View})
is a convenient way to get a rough feeling of the time-step sizes.
\end{enumerate}
\subsubsection{Exercise 2}
For this exercise, first create a new problem file analogous to the
file \texttt{tutorial1problem.hh} (e.g. with the name
\texttt{ex2\_tutorial1problem.hh}. The new problem
file needs to be included in the file \texttt{tutorial1.cc}.
The new file should contain definitions of new classes with names that
relate to the file name, such as
\texttt{Ex2TutorialProblemCoupled}. Make sure that you also adjust the
guardian macros in lines \ref{tutorial1:guardian1} and
\ref{tutorial1:guardian1} in the header files (e.g. change
\mbox{\texttt{EWOMS\_TUTORIAL1PROBLEM\_HH}} to
\mbox{\texttt{EWOMS\_EX2\_TUTORIAL1PROBLEM\_HH}}). Include the
new problem file in \texttt{tutorial1.cc}. Besides adjusting
the guardian macros, the new problem file should define and use a new
type tag for the problem as well as a new problem class
e.g. \mbox{\texttt{Ex2TutorialProblemCoupled}}. The type tag for the
problem should be adjusted, too. For this, modify line
\ref{tutorial1:set-type-tag} in the problem file and the adapt
the \texttt{main} function in the file \texttt{tutorial1.cc}.
After this, change the domain parameters so that they match the domain
described by figure \ref{tutorial1:ex2_Domain}. Adapt the
problem class so that the boundary conditions are consistent with
figure \ref{tutorial1:ex2_BC}. Initially, the domain is fully
saturated with water and the pressure is $p_w = 5\cdot
10^5\;\text{Pa}$. Oil infiltrates from the left side. Create a grid
with $20$ cells in $x$-direction and $10$ cells in $y$-direction. The
simulation time should end at $10^6\;\text{s}$ with an initial time
step size of $100\;\text{s}$.
\begin{figure}[ht]
\psfrag{K1}{K $= 10^{-7}\;\text{m}^2$}
\psfrag{phi1}{$\phi = 0.2$}
\psfrag{Lin}{\textsc{Brooks}-\textsc{Corey} Law}
\psfrag{Lin2}{$\lambda = 1.8$, $p_e = 1000\;\text{Pa}$}
\psfrag{K2}{K $= 10^{-9}\;\text{m}^2$}
\psfrag{phi2}{$\phi = 0.15$}
\psfrag{BC1}{\textsc{Brooks}-\textsc{Corey} Law}
\psfrag{BC2}{$\lambda = 2$, $p_e = 1500\;\text{Pa}$}
\psfrag{H1y}{$50\;\text{m}$}
\psfrag{H2y}{$15\;\text{m}$}
\psfrag{H3y}{$20\;\text{m}$}
\psfrag{L1x}{$100\;\text{m}$}
\psfrag{L2x}{$50\;\text{m}$}
\psfrag{L3x}{$25\;\text{m}$}
\centering
\includegraphics[width=0.8\linewidth,keepaspectratio]{EPS/Ex2_Domain.eps}
\caption{Set-up of the model domain and the soil parameters}\label{tutorial1:ex2_Domain}
\end{figure}
\begin{figure}[ht]
\psfrag{pw}{$p_w = 5 \times 10^5\;\text{Pa}$}
\psfrag{S}{$S_n = 1.0$}
\psfrag{qw}{$q_w = 2 \times 10^{-4} \;\text{kg}/\text{m}^2\text{s}$}
\psfrag{qo}{$q_n = 0.0 \;\text{kg}/\text{m}^2\text{s}$}
\psfrag{no flow}{no flow}
\centering
\includegraphics[width=0.8\linewidth,keepaspectratio]{EPS/Ex2_Boundary.eps}
\caption{Boundary Conditions}\label{tutorial1:ex2_BC}
\end{figure}
\begin{itemize}
\item Increase the simulation time to e.g. $4\times 10^7
\;\text{s}$. Investigate the saturation of the wetting phas: Is the
value range reasonable?
\item What happens if you use a grid with more cells in each direction?
\end{itemize}
\subsubsection{Exercise 3: Create a New Component}
Create a new file for the benzene component called \texttt{benzene.hh}
and implement a new component. (\textbf{Hint:} The easiest way to do
this is to copy and modify one of the existing components located in
the directory \texttt{ewoms/material/components}.) Use benzene as a
new non-wetting fluid and run the problem of Exercise 2 with water and
benzene. Benzene has a density of $889.51 \, \text{kg} / \text{m}^3$
and a viscosity of $0.00112 \, \text{Pa} \; \text{s}$.
\clearpage \newpage
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "ewoms-handbook"
%%% End:

File diff suppressed because it is too large Load Diff

286
examples/art2dgf.cpp Normal file
View File

@ -0,0 +1,286 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
#include <dune/common/version.hh>
#include <dune/common/fvector.hh>
#include <dune/common/fmatrix.hh>
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <memory>
#include <stdexcept>
#include <sstream>
#include <string>
#include <vector>
namespace Ewoms {
/*!
* \brief Reads in mesh files in the ART format.
*
* This file format is used to specify grids with fractures.
*/
struct Art2DGF
{
/*!
* \brief Create the Grid
*/
static void convert( const std::string& artFileName,
std::ostream& dgfFile,
const unsigned precision = 16 )
{
using Scalar = double;
using GlobalPosition = Dune::FieldVector< Scalar, 2 >;
enum ParseMode { Vertex, Edge, Element, Finished };
std::vector< std::pair<GlobalPosition, unsigned> > vertexPos;
std::vector<std::pair<unsigned, unsigned> > edges;
std::vector<std::pair<unsigned, unsigned> > fractureEdges;
std::vector<std::vector<unsigned> > elements;
std::ifstream inStream(artFileName);
if (!inStream.is_open()) {
throw std::runtime_error("File '"+artFileName
+"' does not exist or is not readable");
}
std::string curLine;
ParseMode curParseMode = Vertex;
while (inStream) {
std::getline(inStream, curLine);
// remove comments
auto commentPos = curLine.find("%");
if (commentPos != curLine.npos) {
curLine = curLine.substr(0, commentPos);
}
// remove leading whitespace
unsigned numLeadingSpaces = 0;
while (curLine.size() > numLeadingSpaces
&& std::isspace(curLine[numLeadingSpaces]))
++numLeadingSpaces;
curLine = curLine.substr(numLeadingSpaces,
curLine.size() - numLeadingSpaces);
// remove trailing whitespace
unsigned numTrailingSpaces = 0;
while (curLine.size() > numTrailingSpaces
&& std::isspace(curLine[curLine.size() - numTrailingSpaces]))
++numTrailingSpaces;
curLine = curLine.substr(0, curLine.size() - numTrailingSpaces);
// a section of the file is finished, go to the next one
if (curLine == "$") {
if (curParseMode == Vertex)
curParseMode = Edge;
else if (curParseMode == Edge)
curParseMode = Element;
else if (curParseMode == Element)
curParseMode = Finished;
continue;
}
// skip empty lines
if (curLine.empty())
continue;
if (curParseMode == Vertex) {
GlobalPosition coord;
std::istringstream iss(curLine);
// parse only the first two numbers as the vertex
// coordinate. the last number is the Z coordinate
// which we ignore (so far)
iss >> coord[0] >> coord[1];
vertexPos.push_back( std::make_pair( coord, 0 ) );
}
else if (curParseMode == Edge) {
// read an edge and update the fracture mapper
// read the data attached to the edge
std::istringstream iss(curLine);
int dataVal;
std::string tmp;
iss >> dataVal;
iss >> tmp;
assert(tmp == ":");
// read the vertex indices of an edge
std::vector<unsigned int> vertIndices;
while (iss) {
unsigned int tmp2;
iss >> tmp2;
if (!iss)
break;
vertIndices.push_back(tmp2);
assert(tmp2 < vertexPos.size());
}
// an edge always has two indices!
assert(vertIndices.size() == 2);
std::pair<unsigned, unsigned> edge(vertIndices[0], vertIndices[1]);
edges.push_back(edge);
// add the edge to the fracture mapper if it is a fracture
if (dataVal < 0) {
fractureEdges.push_back(edge);
vertexPos[ edge.first ].second = 1;
vertexPos[ edge.second ].second = 1;
}
}
else if (curParseMode == Element) {
// skip the data attached to an element
std::istringstream iss(curLine);
int dataVal;
std::string tmp;
iss >> dataVal;
iss >> tmp;
assert(tmp == ":");
// read the edge indices of an element
std::vector<unsigned> edgeIndices;
while (iss) {
unsigned tmp2;
iss >> tmp2;
if (!iss)
break;
edgeIndices.push_back(tmp2);
assert(tmp2 < edges.size());
}
// so far, we only support triangles
assert(edgeIndices.size() == 3);
// extract the vertex indices of the element
std::vector<unsigned> vertIndices;
for (unsigned i = 0; i < 3; ++i) {
bool haveFirstVertex = false;
for (unsigned j = 0; j < vertIndices.size(); ++j) {
assert(edgeIndices[i] < edges.size());
if (vertIndices[j] == edges[edgeIndices[i]].first) {
haveFirstVertex = true;
break;
}
}
if (!haveFirstVertex)
vertIndices.push_back(edges[edgeIndices[i]].first);
bool haveSecondVertex = false;
for (unsigned j = 0; j < vertIndices.size(); ++j) {
assert(edgeIndices[i] < edges.size());
if (vertIndices[j] == edges[edgeIndices[i]].second) {
haveSecondVertex = true;
break;
}
}
if (!haveSecondVertex)
vertIndices.push_back(edges[edgeIndices[i]].second);
}
// check whether the element's vertices are given in
// mathematically positive direction. if not, swap the
// first two.
Dune::FieldMatrix<Scalar, 2, 2> mat;
mat[0] = vertexPos[vertIndices[1]].first;
mat[0] -= vertexPos[vertIndices[0]].first;
mat[1] = vertexPos[vertIndices[2]].first;
mat[1] -= vertexPos[vertIndices[0]].first;
assert(std::abs(mat.determinant()) > 1e-50);
if (mat.determinant() < 0)
std::swap(vertIndices[2], vertIndices[1]);
elements.push_back( vertIndices );
}
else if (curParseMode == Finished) {
assert(curLine.size() == 0);
}
}
dgfFile << "DGF" << std::endl << std::endl;
dgfFile << "GridParameter" << std::endl
<< "overlap 1" << std::endl
<< "closure green" << std::endl
<< "#" << std::endl << std::endl;
dgfFile << "Vertex" << std::endl;
const bool hasFractures = fractureEdges.size() > 0;
if( hasFractures )
{
dgfFile << "parameters 1" << std::endl;
}
dgfFile << std::scientific;
dgfFile.precision( precision );
const size_t vxSize = vertexPos.size();
for( size_t i=0; i<vxSize; ++i)
{
dgfFile << vertexPos[ i ].first;
if( hasFractures )
{
dgfFile << " " << vertexPos[ i ].second;
}
dgfFile << std::endl;
}
dgfFile << "#" << std::endl << std::endl;
dgfFile << "Simplex" << std::endl;
const size_t elSize = elements.size();
for( size_t i=0; i<elSize; ++i )
{
const size_t elVx = elements[ i ].size();
for( size_t j=0; j<elVx; ++j )
dgfFile << elements[ i ][ j ] << " ";
dgfFile << std::endl;
}
dgfFile << "#" << std::endl << std::endl;
dgfFile << "BoundaryDomain" << std::endl;
dgfFile << "default 1" << std::endl;
dgfFile << "#" << std::endl << std::endl;
dgfFile << "#" << std::endl;
}
};
} // namespace Ewoms
int main( int argc, char** argv )
{
if (argc != 2) {
std::cout << "Converts a grid file from the ART file format to DGF (Dune grid format)\n"
<< "\n"
<< "Usage: " << argv[0] << " ART_FILENAME\n"
<< "\n"
<< "The result will be written to the file $ART_FILENAME.dgf\n";
return 1;
}
std::string filename( argv[ 1 ] );
std::string dgfname( filename );
dgfname += ".dgf";
std::cout << "Converting ART file \"" << filename << "\" to DGF file \"" << dgfname << "\"\n";
std::ofstream dgfFile( dgfname );
Ewoms::Art2DGF::convert( filename, dgfFile );
return 0;
}

View File

@ -0,0 +1,62 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Box problem with two phases and multiple components.
* Solved with a PTFlash two phase solver.
*/
#include "config.h"
#include <opm/models/utils/start.hh>
#include "problems/co2ptflashproblem.hh"
namespace Opm::Properties {
namespace TTag {
struct CO2PTEcfvProblem {
using InheritsFrom = std::tuple<CO2PTBaseProblem, FlashModel>;
};
}
template <class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::CO2PTEcfvProblem>
{
using type = TTag::EcfvDiscretization;
};
template <class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::CO2PTEcfvProblem>
{
using type = TTag::AutoDiffLocalLinearizer;
};
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using EcfvProblemTypeTag = Opm::Properties::TTag::CO2PTEcfvProblem;
return Opm::start<EcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,85 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the isothermal compositional model based on flash
* calculations.
*/
#include "config.h"
#if HAVE_QUAD
#include <opm/material/common/quad.hpp>
#endif
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/flash/flashmodel.hh>
#include <opm/models/discretization/ecfv/ecfvdiscretization.hh>
#include "problems/co2injectionflash.hh"
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct Co2InjectionFlashEcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, FlashModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionFlashEcfvProblem>
{ using type = TTag::EcfvDiscretization; };
// use automatic differentiation for this simulator
template<class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::Co2InjectionFlashEcfvProblem>
{ using type = TTag::AutoDiffLocalLinearizer; };
// use the flash solver adapted to the CO2 injection problem
template<class TypeTag>
struct FlashSolver<TypeTag, TTag::Co2InjectionFlashEcfvProblem>
{ using type = Opm::Co2InjectionFlash<GetPropType<TypeTag, Properties::Scalar>,
GetPropType<TypeTag, Properties::FluidSystem>>; };
// the flash model has serious problems with the numerical
// precision. if quadruple precision math is available, we use it,
// else we increase the tolerance of the Newton solver
#if HAVE_QUAD
template<class TypeTag>
struct Scalar<TypeTag, TTag::Co2InjectionFlashEcfvProblem>
{ using type = quad; };
#endif
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using EcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionFlashEcfvProblem;
#if ! HAVE_QUAD
Opm::Co2InjectionTolerance = 1e-5;
#endif
return Opm::start<EcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,87 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the non-isothermal compositional model based on flash
* calculations.
*/
#include "config.h"
// this must be included before the vanguard
#include <opm/material/common/quad.hpp>
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/flash/flashmodel.hh>
#include <opm/models/discretization/ecfv/ecfvdiscretization.hh>
#include "problems/co2injectionflash.hh"
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct Co2InjectionFlashNiEcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, FlashModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionFlashNiEcfvProblem>
{ using type = TTag::EcfvDiscretization; };
template<class TypeTag>
struct EnableEnergy<TypeTag, TTag::Co2InjectionFlashNiEcfvProblem>
{ static constexpr bool value = true; };
//! Use automatic differentiation to linearize the system of PDEs
template<class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::Co2InjectionFlashNiEcfvProblem>
{ using type = TTag::AutoDiffLocalLinearizer; };
// use the CO2 injection problem adapted flash solver
template<class TypeTag>
struct FlashSolver<TypeTag, TTag::Co2InjectionFlashNiEcfvProblem>
{ using type = Opm::Co2InjectionFlash<GetPropType<TypeTag, Properties::Scalar>,
GetPropType<TypeTag, Properties::FluidSystem>>; };
// the flash model has serious problems with the numerical
// precision. if quadruple precision math is available, we use it,
// else we increase the tolerance of the Newton solver
#if HAVE_QUAD
template<class TypeTag>
struct Scalar<TypeTag, TTag::Co2InjectionFlashNiEcfvProblem>
{ using type = quad; };
#endif
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using EcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionFlashNiEcfvProblem;
#if ! HAVE_QUAD
Opm::Co2InjectionTolerance = 1e-5;
#endif
return Opm::start<EcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,83 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the non-isothermal compositional model based on flash
* calculations.
*/
#include "config.h"
// this must be included before the vanguard
#include <opm/material/common/quad.hpp>
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/flash/flashmodel.hh>
#include <opm/models/discretization/vcfv/vcfvdiscretization.hh>
#include "problems/co2injectionflash.hh"
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct Co2InjectionFlashNiVcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, FlashModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionFlashNiVcfvProblem>
{ using type = TTag::VcfvDiscretization; };
template<class TypeTag>
struct EnableEnergy<TypeTag, TTag::Co2InjectionFlashNiVcfvProblem>
{ static constexpr bool value = true; };
// use the CO2 injection problem adapted flash solver
template<class TypeTag>
struct FlashSolver<TypeTag, TTag::Co2InjectionFlashNiVcfvProblem>
{ using type = Opm::Co2InjectionFlash<GetPropType<TypeTag, Properties::Scalar>,
GetPropType<TypeTag, Properties::FluidSystem>>; };
// the flash model has serious problems with the numerical
// precision. if quadruple precision math is available, we use it,
// else we increase the tolerance of the Newton solver
#if HAVE_QUAD
template<class TypeTag>
struct Scalar<TypeTag, TTag::Co2InjectionFlashNiVcfvProblem>
{ using type = quad; };
#endif
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using VcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionFlashNiVcfvProblem;
#if ! HAVE_QUAD
Opm::Co2InjectionTolerance = 1e-5;
#endif
return Opm::start<VcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,79 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the isothermal compositional model based on flash
* calculations.
*/
#include "config.h"
#if HAVE_QUAD
#include <opm/material/common/quad.hpp>
#endif
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/flash/flashmodel.hh>
#include <opm/models/discretization/vcfv/vcfvdiscretization.hh>
#include "problems/co2injectionflash.hh"
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct Co2InjectionFlashVcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, FlashModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionFlashVcfvProblem>
{ using type = TTag::VcfvDiscretization; };
// use the flash solver adapted to the CO2 injection problem
template<class TypeTag>
struct FlashSolver<TypeTag, TTag::Co2InjectionFlashVcfvProblem>
{ using type = Opm::Co2InjectionFlash<GetPropType<TypeTag, Properties::Scalar>,
GetPropType<TypeTag, Properties::FluidSystem>>; };
// the flash model has serious problems with the numerical
// precision. if quadruple precision math is available, we use it,
// else we increase the tolerance of the Newton solver
#if HAVE_QUAD
template<class TypeTag>
struct Scalar<TypeTag, TTag::Co2InjectionFlashVcfvProblem>
{ using type = quad; };
#endif
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using VcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionFlashVcfvProblem;
#if ! HAVE_QUAD
Opm::Co2InjectionTolerance = 1e-5;
#endif
return Opm::start<VcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,60 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the isothermal immiscible model using the CO2 injection
* example problem
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/immiscible/immisciblemodel.hh>
#include <opm/models/discretization/ecfv/ecfvdiscretization.hh>
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
namespace TTag {
struct Co2InjectionImmiscibleEcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, ImmiscibleModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionImmiscibleEcfvProblem>
{ using type = TTag::EcfvDiscretization; };
} // namespace Opm::Properties
////////////////////////
// the main function
////////////////////////
int main(int argc, char **argv)
{
using EcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionImmiscibleEcfvProblem;
return Opm::start<EcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,68 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Simulation of the injection problem using the VCVF discretization
* assuming immisicibility and with energy enabled.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/immiscible/immisciblemodel.hh>
#include <opm/models/discretization/ecfv/ecfvdiscretization.hh>
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct Co2InjectionImmiscibleNiEcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, ImmiscibleModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionImmiscibleNiEcfvProblem>
{ using type = TTag::EcfvDiscretization; };
template<class TypeTag>
struct EnableEnergy<TypeTag, TTag::Co2InjectionImmiscibleNiEcfvProblem>
{ static constexpr bool value = true; };
//! Use automatic differentiation to linearize the system of PDEs
template<class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::Co2InjectionImmiscibleNiEcfvProblem>
{ using type = TTag::AutoDiffLocalLinearizer; };
} // namespace Opm::Properties
////////////////////////
// the main function
////////////////////////
int main(int argc, char **argv)
{
using EcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionImmiscibleNiEcfvProblem;
return Opm::start<EcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,63 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Simulation of the injection problem using the VCVF discretization
* assuming immisicibility and with energy enabled.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/immiscible/immisciblemodel.hh>
#include <opm/models/discretization/vcfv/vcfvdiscretization.hh>
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
namespace TTag {
struct Co2InjectionImmiscibleNiVcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, ImmiscibleModel>; };
} // namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionImmiscibleNiVcfvProblem>
{ using type = TTag::VcfvDiscretization; };
template<class TypeTag>
struct EnableEnergy<TypeTag, TTag::Co2InjectionImmiscibleNiVcfvProblem>
{ static constexpr bool value = true; };
} // namespace Opm::Properties
////////////////////////
// the main function
////////////////////////
int main(int argc, char **argv)
{
using VcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionImmiscibleNiVcfvProblem;
return Opm::start<VcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,60 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the isothermal immiscible model using the CO2 injection
* example problem
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/immiscible/immisciblemodel.hh>
#include <opm/models/discretization/vcfv/vcfvdiscretization.hh>
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
namespace TTag {
struct Co2InjectionImmiscibleVcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, ImmiscibleModel>; };
} // namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionImmiscibleVcfvProblem>
{ using type = TTag::VcfvDiscretization; };
} // namespace Opm::Properties
////////////////////////
// the main function
////////////////////////
int main(int argc, char **argv)
{
using VcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionImmiscibleVcfvProblem;
return Opm::start<VcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,57 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the isothermal VCVF discretization based on non-linear
* complementarity problems.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/ncp/ncpmodel.hh>
#include <opm/models/discretization/ecfv/ecfvdiscretization.hh>
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct Co2InjectionNcpEcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, NcpModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionNcpEcfvProblem>
{ using type = TTag::EcfvDiscretization; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using EcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionNcpEcfvProblem;
return Opm::start<EcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,66 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the non-isothermal VCVF discretization based on non-linear
* complementarity problems.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/ncp/ncpmodel.hh>
#include <opm/models/discretization/ecfv/ecfvdiscretization.hh>
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct Co2InjectionNcpNiEcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, NcpModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionNcpNiEcfvProblem>
{ using type = TTag::EcfvDiscretization; };
template<class TypeTag>
struct EnableEnergy<TypeTag, TTag::Co2InjectionNcpNiEcfvProblem>
{ static constexpr bool value = true; };
//! Use automatic differentiation to linearize the system of PDEs
template<class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::Co2InjectionNcpNiEcfvProblem>
{ using type = TTag::AutoDiffLocalLinearizer; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using EcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionNcpNiEcfvProblem;
return Opm::start<EcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,60 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the non-isothermal VCVF discretization based on non-linear
* complementarity problems.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/ncp/ncpmodel.hh>
#include <opm/models/discretization/vcfv/vcfvdiscretization.hh>
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct Co2InjectionNcpNiVcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, NcpModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionNcpNiVcfvProblem>
{ using type = TTag::VcfvDiscretization; };
template<class TypeTag>
struct EnableEnergy<TypeTag, TTag::Co2InjectionNcpNiVcfvProblem>
{ static constexpr bool value = true; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using VcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionNcpNiVcfvProblem;
return Opm::start<VcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,58 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the isothermal VCVF discretization based on non-linear
* complementarity problems.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/ncp/ncpmodel.hh>
#include <opm/models/discretization/vcfv/vcfvdiscretization.hh>
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct Co2InjectionNcpVcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, NcpModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionNcpVcfvProblem>
{ using type = TTag::VcfvDiscretization; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using VcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionNcpVcfvProblem;
return Opm::start<VcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,57 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the isothermal primary variable switching model
* using the ECVF discretization.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/pvs/pvsmodel.hh>
#include <opm/models/discretization/ecfv/ecfvdiscretization.hh>
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct Co2InjectionPvsEcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, PvsModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionPvsEcfvProblem>
{ using type = TTag::EcfvDiscretization; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using EcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionPvsEcfvProblem;
return Opm::start<EcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,65 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the non-isothermal primary variable switching VCVF
* discretization.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/pvs/pvsmodel.hh>
#include <opm/models/discretization/ecfv/ecfvdiscretization.hh>
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct Co2InjectionPvsNiEcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, PvsModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionPvsNiEcfvProblem>
{ using type = TTag::EcfvDiscretization; };
template<class TypeTag>
struct EnableEnergy<TypeTag, TTag::Co2InjectionPvsNiEcfvProblem>
{ static constexpr bool value = true; };
//! Use automatic differentiation to linearize the system of PDEs
template<class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::Co2InjectionPvsNiEcfvProblem>
{ using type = TTag::AutoDiffLocalLinearizer; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using EcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionPvsNiEcfvProblem;
return Opm::start<EcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,61 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the non-isothermal primary variable switching model
* using the VCVF discretization.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/pvs/pvsmodel.hh>
#include <opm/models/discretization/vcfv/vcfvdiscretization.hh>
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct Co2InjectionPvsNiVcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, PvsModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionPvsNiVcfvProblem>
{ using type = TTag::VcfvDiscretization; };
template<class TypeTag>
struct EnableEnergy<TypeTag, TTag::Co2InjectionPvsNiVcfvProblem>
{ static constexpr bool value = true; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using VcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionPvsNiVcfvProblem;
return Opm::start<VcfvProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,58 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the isothermal primary variable switching model using the VCVF
* discretization.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/pvs/pvsmodel.hh>
#include <opm/models/discretization/vcfv/vcfvdiscretization.hh>
#include "problems/co2injectionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct Co2InjectionPvsVcfvProblem
{ using InheritsFrom = std::tuple<Co2InjectionBaseProblem, PvsModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::Co2InjectionPvsVcfvProblem>
{ using type = TTag::VcfvDiscretization; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using VcfvProblemTypeTag = Opm::Properties::TTag::Co2InjectionPvsVcfvProblem;
return Opm::start<VcfvProblemTypeTag>(argc, argv);
}

52
examples/cuvette_pvs.cpp Normal file
View File

@ -0,0 +1,52 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief test for the 3p3cni VCVF discretization
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/pvs/pvsmodel.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/cuvetteproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct CuvetteProblem
{ using InheritsFrom = std::tuple<CuvetteBaseProblem, PvsModel>; };
} // end namespace TTag
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::CuvetteProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,48 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the Forchheimer velocity model
*/
#include "config.h"
#include <opm/models/utils/start.hh>
#include <opm/models/flash/flashmodel.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/diffusionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct DiffusionProblem { using InheritsFrom = std::tuple<DiffusionBaseProblem, FlashModel>; };
} // end namespace TTag
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::DiffusionProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,49 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the Forchheimer velocity model
*/
#include "config.h"
#include <opm/models/utils/start.hh>
#include <opm/models/ncp/ncpmodel.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/diffusionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct DiffusionProblem { using InheritsFrom = std::tuple<DiffusionBaseProblem, NcpModel>; };
} // end namespace TTag
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::DiffusionProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,48 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the Forchheimer velocity model
*/
#include "config.h"
#include <opm/models/utils/start.hh>
#include <opm/models/pvs/pvsmodel.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/diffusionproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct DiffusionProblem { using InheritsFrom = std::tuple<DiffusionBaseProblem, PvsModel>; };
} // end namespace TTag
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::DiffusionProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,52 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Problem featuring a saturation overshoot.
*/
#include "config.h"
#include <opm/models/utils/start.hh>
#include <opm/models/immiscible/immisciblemodel.hh>
#include <opm/models/discretization/ecfv/ecfvdiscretization.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/fingerproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct FingerProblemEcfv { using InheritsFrom = std::tuple<FingerBaseProblem, ImmiscibleTwoPhaseModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::FingerProblemEcfv> { using type = TTag::EcfvDiscretization; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::FingerProblemEcfv;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,52 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Problem featuring a saturation overshoot.
*/
#include "config.h"
#include <opm/models/utils/start.hh>
#include <opm/models/immiscible/immisciblemodel.hh>
#include <opm/models/discretization/vcfv/vcfvdiscretization.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/fingerproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct FingerProblemVcfv { using InheritsFrom = std::tuple<FingerBaseProblem, ImmiscibleTwoPhaseModel>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::FingerProblemVcfv> { using type = TTag::VcfvDiscretization; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::FingerProblemVcfv;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,39 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Two-phase problem test with fractures.
*/
#include "config.h"
#include <opm/models/utils/start.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/fractureproblem.hh"
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::FractureProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,51 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the immisicible VCVF discretization with only a single phase
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/immiscible/immisciblemodel.hh>
#include "problems/groundwaterproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct GroundWaterProblem
{ using InheritsFrom = std::tuple<GroundWaterBaseProblem, ImmiscibleSinglePhaseModel>; };
} // end namespace TTag
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::GroundWaterProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,50 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief test for the primary variable switching VCVF discretization
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/pvs/pvsmodel.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/infiltrationproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct InfiltrationProblem
{ using InheritsFrom = std::tuple<InfiltrationBaseProblem, PvsModel>; };
} // end namespace TTag
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::InfiltrationProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,40 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Two-phase test for the immiscible model which uses the element-centered finite
* volume discretization in conjunction with automatic differentiation
*/
#include "config.h"
#include "lens_immiscible_ecfv_ad.hh"
#include <opm/models/utils/start.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::LensProblemEcfvAd;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,57 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Two-phase test for the immiscible model which uses the element-centered finite
* volume discretization in conjunction with automatic differentiation
*/
#ifndef EWOMS_LENS_IMMISCIBLE_ECFV_AD_HH
#define EWOMS_LENS_IMMISCIBLE_ECFV_AD_HH
#include <opm/models/immiscible/immisciblemodel.hh>
#include <opm/models/discretization/ecfv/ecfvdiscretization.hh>
#include "problems/lensproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct LensProblemEcfvAd { using InheritsFrom = std::tuple<LensBaseProblem, ImmiscibleTwoPhaseModel>; };
} // end namespace TTag
// use the element centered finite volume spatial discretization
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::LensProblemEcfvAd> { using type = TTag::EcfvDiscretization; };
// use automatic differentiation for this simulator
template<class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::LensProblemEcfvAd> { using type = TTag::AutoDiffLocalLinearizer; };
// this problem works fine if the linear solver uses single precision scalars
template<class TypeTag>
struct LinearSolverScalar<TypeTag, TTag::LensProblemEcfvAd> { using type = float; };
} // namespace Opm::Properties
#endif // EWOMS_LENS_IMMISCIBLE_ECFV_AD_HH

View File

@ -0,0 +1,93 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Two-phase test for the immiscible model which uses the element-centered finite
* volume discretization in conjunction with automatic differentiation
*/
#include "config.h"
#include "lens_immiscible_ecfv_ad.hh"
#include <dune/grid/geometrygrid.hh>
#include <dune/grid/io/file/dgfparser/dgfgeogrid.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
namespace Opm::Properties {
// Use Dune-grid's GeometryGrid< YaspGrid >
template<class TypeTag>
struct Grid <TypeTag, TTag::LensProblemEcfvAd>
{
template< class ctype, unsigned int dim, unsigned int dimworld >
class IdentityCoordFct
: public Dune::AnalyticalCoordFunction
< ctype, dim, dimworld, IdentityCoordFct< ctype, dim, dimworld > >
{
using This = IdentityCoordFct< ctype, dim, dimworld >;
using Base = Dune::AnalyticalCoordFunction< ctype, dim, dimworld, This >;
public:
using DomainVector = typename Base :: DomainVector;
using RangeVector = typename Base :: RangeVector ;
template< typename... Args >
IdentityCoordFct( Args&... )
{}
RangeVector operator()(const DomainVector& x) const
{
RangeVector y;
evaluate( x, y );
return y;
}
void evaluate( const DomainVector &x, RangeVector &y ) const
{
y = 0;
for( unsigned int i = 0; i<dim; ++i )
y[ i ] = x[ i ];
}
};
using MyYaspGrid = Dune::YaspGrid< 2 >;
public:
using type = Dune::GeometryGrid< MyYaspGrid,
IdentityCoordFct< typename MyYaspGrid::ctype,
MyYaspGrid::dimension,
MyYaspGrid::dimensionworld+1> >;
};
} // namespace Opm::Properties
#include <opm/models/utils/start.hh>
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::LensProblemEcfvAd;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,49 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief This test is identical to the simulation of the lens problem that uses the
* element centered finite volume discretization in conjunction with automatic
* differentiation (lens_immiscible_ecfv_ad).
*
* The only difference is that it uses multiple compile units in order to ensure that
* eWoms code can be used within libraries that use the same type tag within multiple
* compile units. This file represents the first compile unit and just defines an startup
* function for the simulator.
*/
#include "config.h"
#include "lens_immiscible_ecfv_ad.hh"
#include <opm/models/utils/start.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
// fake forward declaration to prevent esoteric compiler warning
int mainCU1(int argc, char **argv);
int mainCU1(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::LensProblemEcfvAd;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,49 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief This test is identical to the simulation of the lens problem that uses the
* element centered finite volume discretization in conjunction with automatic
* differentiation (lens_immiscible_ecfv_ad).
*
* The only difference is that it uses multiple compile units in order to ensure that
* eWoms code can be used within libraries that use the same type tag within multiple
* compile units. This file represents the second compile unit and just defines an
* startup function for the simulator.
*/
#include "config.h"
#include "lens_immiscible_ecfv_ad.hh"
#include <opm/models/utils/start.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
// fake forward declaration to prevent esoteric compiler warning
int mainCU2(int argc, char **argv);
int mainCU2(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::LensProblemEcfvAd;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,41 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief This test is identical to the simulation of the lens problem that uses the
* element centered finite volume discretization in conjunction with automatic
* differentiation (lens_immiscible_ecfv_ad).
*
* The only difference is that it uses multiple compile units in order to ensure that
* eWoms code can be used within libraries that use the same type tag within multiple
* compile units. This file calls contains main() and just calls the main entry point
* defined by the first compile unit.
*/
int mainCU1(int argc, char **argv);
int mainCU2(int argc, char **argv);
int main(int argc, char **argv)
{
return mainCU1(argc, argv);
}

View File

@ -0,0 +1,66 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Two-phase test for the immiscible model which uses the element-centered finite
* volume discretization with two-point-flux using the transmissibility module
* in conjunction with automatic differentiation
*/
#include "config.h"
#include <opm/models/immiscible/immisciblemodel.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/discretization/ecfv/ecfvdiscretization.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/lensproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct LensProblemEcfvAdTrans { using InheritsFrom = std::tuple<LensBaseProblem, ImmiscibleTwoPhaseModel>; };
} // end namespace TTag
// use automatic differentiation for this simulator
template<class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::LensProblemEcfvAdTrans> { using type = TTag::AutoDiffLocalLinearizer; };
// use the element centered finite volume spatial discretization
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::LensProblemEcfvAdTrans> { using type = TTag::EcfvDiscretization; };
// Set the problem property
template <class TypeTag>
struct FluxModule<TypeTag, TTag::LensProblemEcfvAdTrans> {
using type = TransFluxModule<TypeTag>;
};
}
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::LensProblemEcfvAdTrans;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,60 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Two-phase test for the immiscible model which uses the
* vertex-centered finite volume discretization
*/
#include "config.h"
#include <opm/models/utils/start.hh>
#include <opm/models/immiscible/immisciblemodel.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/lensproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct LensProblemVcfvAd { using InheritsFrom = std::tuple<LensBaseProblem, ImmiscibleTwoPhaseModel>; };
} // end namespace TTag
// use automatic differentiation for this simulator
template<class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::LensProblemVcfvAd> { using type = TTag::AutoDiffLocalLinearizer; };
// use linear finite element gradients if dune-localfunctions is available
#if HAVE_DUNE_LOCALFUNCTIONS
template<class TypeTag>
struct UseP1FiniteElementGradients<TypeTag, TTag::LensProblemVcfvAd> { static constexpr bool value = true; };
#endif
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::LensProblemVcfvAd;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,60 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Two-phase test for the immiscible model which uses the
* vertex-centered finite volume discretization
*/
#include "config.h"
#include <opm/models/utils/start.hh>
#include <opm/models/immiscible/immisciblemodel.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/lensproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct LensProblemVcfvFd { using InheritsFrom = std::tuple<LensBaseProblem, ImmiscibleTwoPhaseModel>; };
} // end namespace TTag
// use the finite difference methodfor this simulator
template<class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::LensProblemVcfvFd> { using type = TTag::FiniteDifferenceLocalLinearizer; };
// use linear finite element gradients if dune-localfunctions is available
#if HAVE_DUNE_LOCALFUNCTIONS
template<class TypeTag>
struct UseP1FiniteElementGradients<TypeTag, TTag::LensProblemVcfvFd> { static constexpr bool value = true; };
#endif
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::LensProblemVcfvFd;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,61 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the Richards model using the ECFV discretization.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/discretization/ecfv/ecfvdiscretization.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/richardslensproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct RichardsLensEcfvProblem
{ using InheritsFrom = std::tuple<RichardsLensProblem>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::RichardsLensEcfvProblem>
{ using type = TTag::EcfvDiscretization; };
//! Use automatic differentiation to linearize the system of PDEs
template<class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::RichardsLensEcfvProblem>
{ using type = TTag::AutoDiffLocalLinearizer; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::RichardsLensEcfvProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,57 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the Richards model using the VCFV discretization.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/discretization/vcfv/vcfvdiscretization.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/richardslensproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct RichardsLensVcfvProblem
{ using InheritsFrom = std::tuple<RichardsLensProblem>; };
} // end namespace TTag
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::RichardsLensVcfvProblem>
{ using type = TTag::VcfvDiscretization; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::RichardsLensVcfvProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,52 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*
* \file
*
* \brief Test for the immiscible multi-phase VCVF discretization.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include <opm/models/immiscible/immisciblemodel.hh>
#include "problems/obstacleproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct ObstacleProblem
{ using InheritsFrom = std::tuple<ObstacleBaseProblem, ImmiscibleModel>; };
} // end namespace TTag
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::ObstacleProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

53
examples/obstacle_ncp.cpp Normal file
View File

@ -0,0 +1,53 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the compositional NCP VCVF discretization.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/ncp/ncpmodel.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/obstacleproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct ObstacleProblem
{ using InheritsFrom = std::tuple<ObstacleBaseProblem, NcpModel>; };
} // end namespace TTag
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::ObstacleProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

55
examples/obstacle_pvs.cpp Normal file
View File

@ -0,0 +1,55 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*
* \file
*
* \brief Test for the isothermal primary variable switching model
* using "obstacle" problem and the VCVF discretization.
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/pvs/pvsmodel.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/obstacleproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct ObstacleProblem
{ using InheritsFrom = std::tuple<ObstacleBaseProblem, PvsModel>; };
} // end namespace TTag
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::ObstacleProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

53
examples/outflow_pvs.cpp Normal file
View File

@ -0,0 +1,53 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief test for the compositional PVS VCVF discretization
*/
#include "config.h"
#include <opm/models/io/dgfvanguard.hh>
#include <opm/models/utils/start.hh>
#include <opm/models/pvs/pvsmodel.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/outflowproblem.hh"
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct OutflowProblem
{ using InheritsFrom = std::tuple<OutflowBaseProblem, PvsModel>; };
} // end namespace TTag
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::OutflowProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,55 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the Forchheimer velocity model
*/
#include "config.h"
#include <opm/models/utils/start.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include <opm/models/immiscible/immisciblemodel.hh>
#include "problems/powerinjectionproblem.hh"
namespace Opm::Properties {
namespace TTag {
struct PowerInjectionDarcyAdProblem
{ using InheritsFrom = std::tuple<PowerInjectionBaseProblem, ImmiscibleTwoPhaseModel>; };
} // namespace TTag
template<class TypeTag>
struct FluxModule<TypeTag, TTag::PowerInjectionDarcyAdProblem> { using type = Opm::DarcyFluxModule<TypeTag>; };
template<class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::PowerInjectionDarcyAdProblem> { using type = TTag::AutoDiffLocalLinearizer; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::PowerInjectionDarcyAdProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,55 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the Forchheimer velocity model
*/
#include "config.h"
#include <opm/models/utils/start.hh>
#include <opm/models/immiscible/immisciblemodel.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/powerinjectionproblem.hh"
namespace Opm::Properties {
namespace TTag {
struct PowerInjectionDarcyFdProblem
{ using InheritsFrom = std::tuple<PowerInjectionBaseProblem, ImmiscibleTwoPhaseModel>; };
} // namespace TTag
template<class TypeTag>
struct FluxModule<TypeTag, TTag::PowerInjectionDarcyFdProblem> { using type = Opm::DarcyFluxModule<TypeTag>; };
template<class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::PowerInjectionDarcyFdProblem> { using type = TTag::FiniteDifferenceLocalLinearizer; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::PowerInjectionDarcyFdProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,55 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the Forchheimer velocity model
*/
#include "config.h"
#include <opm/models/utils/start.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include <opm/models/immiscible/immisciblemodel.hh>
#include "problems/powerinjectionproblem.hh"
namespace Opm::Properties {
namespace TTag {
struct PowerInjectionForchheimerAdProblem
{ using InheritsFrom = std::tuple<PowerInjectionBaseProblem, ImmiscibleTwoPhaseModel>; };
} // namespace TTag
template<class TypeTag>
struct FluxModule<TypeTag, TTag::PowerInjectionForchheimerAdProblem> { using type = Opm::ForchheimerFluxModule<TypeTag>; };
template<class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::PowerInjectionForchheimerAdProblem> { using type = TTag::AutoDiffLocalLinearizer; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::PowerInjectionForchheimerAdProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,55 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \brief Test for the Forchheimer velocity model
*/
#include "config.h"
#include <opm/models/utils/start.hh>
#include <opm/models/immiscible/immisciblemodel.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include "problems/powerinjectionproblem.hh"
namespace Opm::Properties {
namespace TTag {
struct PowerInjectionForchheimerFdProblem
{ using InheritsFrom = std::tuple<PowerInjectionBaseProblem, ImmiscibleTwoPhaseModel>; };
} // namespace TTag
template<class TypeTag>
struct FluxModule<TypeTag, TTag::PowerInjectionForchheimerFdProblem> { using type = Opm::ForchheimerFluxModule<TypeTag>; };
template<class TypeTag>
struct LocalLinearizerSplice<TypeTag, TTag::PowerInjectionForchheimerFdProblem> { using type = TTag::FiniteDifferenceLocalLinearizer; };
} // namespace Opm::Properties
int main(int argc, char **argv)
{
using ProblemTypeTag = Opm::Properties::TTag::PowerInjectionForchheimerFdProblem;
return Opm::start<ProblemTypeTag>(argc, argv);
}

View File

@ -0,0 +1,66 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \copydoc Opm::Co2InjectionFlash
*/
#ifndef EWOMS_CO2_INJECTION_FLASH_HH
#define EWOMS_CO2_INJECTION_FLASH_HH
#include <opm/material/constraintsolvers/NcpFlash.hpp>
namespace Opm {
/*!
* \brief Flash solver used by the CO2 injection problem.
*
* This class is just the NCP flash solver with the guessInitial()
* method that is adapted to the pressure regime of the CO2 injection
* problem.
*/
template <class Scalar, class FluidSystem>
class Co2InjectionFlash : public Opm::NcpFlash<Scalar, FluidSystem>
{
using ParentType = Opm::NcpFlash<Scalar, FluidSystem>;
enum { numPhases = FluidSystem::numPhases };
public:
/*!
* \brief Guess initial values for all quantities.
*/
template <class FluidState, class ComponentVector>
static void guessInitial(FluidState& fluidState, const ComponentVector& globalMolarities)
{
ParentType::guessInitial(fluidState, globalMolarities);
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
// pressure. use something close to the reservoir pressure as initial guess
fluidState.setPressure(phaseIdx, 100e5);
}
}
};
} // namespace Opm
#endif // EWOMS_CO2_INJECTION_FLASH_HH

View File

@ -0,0 +1,648 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \copydoc Opm::Co2InjectionProblem
*/
#ifndef EWOMS_CO2_INJECTION_PROBLEM_HH
#define EWOMS_CO2_INJECTION_PROBLEM_HH
#include <opm/models/immiscible/immisciblemodel.hh>
#include <opm/simulators/linalg/parallelamgbackend.hh>
#include <opm/material/fluidsystems/H2ON2FluidSystem.hpp>
#include <opm/material/fluidsystems/BrineCO2FluidSystem.hpp>
#include <opm/material/fluidstates/CompositionalFluidState.hpp>
#include <opm/material/fluidstates/ImmiscibleFluidState.hpp>
#include <opm/material/constraintsolvers/ComputeFromReferencePhase.hpp>
#include <opm/material/fluidmatrixinteractions/LinearMaterial.hpp>
#include <opm/material/fluidmatrixinteractions/RegularizedBrooksCorey.hpp>
#include <opm/material/fluidmatrixinteractions/EffToAbsLaw.hpp>
#include <opm/material/fluidmatrixinteractions/MaterialTraits.hpp>
#include <opm/material/thermal/SomertonThermalConductionLaw.hpp>
#include <opm/material/thermal/ConstantSolidHeatCapLaw.hpp>
#include <opm/material/binarycoefficients/Brine_CO2.hpp>
#include <opm/material/common/UniformTabulated2DFunction.hpp>
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/io/file/dgfparser/dgfyasp.hh>
#include <dune/common/version.hh>
#include <dune/common/fvector.hh>
#include <dune/common/fmatrix.hh>
#include <sstream>
#include <iostream>
#include <string>
namespace Opm {
//! \cond SKIP_THIS
template <class TypeTag>
class Co2InjectionProblem;
//! \endcond
}
namespace Opm::Properties {
namespace TTag {
struct Co2InjectionBaseProblem {};
}
// Set the grid type
template<class TypeTag>
struct Grid<TypeTag, TTag::Co2InjectionBaseProblem> { using type = Dune::YaspGrid<2>; };
// Set the problem property
template<class TypeTag>
struct Problem<TypeTag, TTag::Co2InjectionBaseProblem>
{ using type = Opm::Co2InjectionProblem<TypeTag>; };
// Set fluid configuration
template<class TypeTag>
struct FluidSystem<TypeTag, TTag::Co2InjectionBaseProblem>
{
private:
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
public:
using type = Opm::BrineCO2FluidSystem<Scalar>;
//using type = Opm::H2ON2FluidSystem<Scalar, /*useComplexRelations=*/false>;
};
// Set the material Law
template<class TypeTag>
struct MaterialLaw<TypeTag, TTag::Co2InjectionBaseProblem>
{
private:
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
enum { liquidPhaseIdx = FluidSystem::liquidPhaseIdx };
enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using Traits = Opm::TwoPhaseMaterialTraits<Scalar,
/*wettingPhaseIdx=*/FluidSystem::liquidPhaseIdx,
/*nonWettingPhaseIdx=*/FluidSystem::gasPhaseIdx>;
// define the material law which is parameterized by effective
// saturations
using EffMaterialLaw = Opm::RegularizedBrooksCorey<Traits>;
public:
// define the material law parameterized by absolute saturations
using type = Opm::EffToAbsLaw<EffMaterialLaw>;
};
// Set the thermal conduction law
template<class TypeTag>
struct ThermalConductionLaw<TypeTag, TTag::Co2InjectionBaseProblem>
{
private:
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
public:
// define the material law parameterized by absolute saturations
using type = Opm::SomertonThermalConductionLaw<FluidSystem, Scalar>;
};
// set the energy storage law for the solid phase
template<class TypeTag>
struct SolidEnergyLaw<TypeTag, TTag::Co2InjectionBaseProblem>
{ using type = Opm::ConstantSolidHeatCapLaw<GetPropType<TypeTag, Properties::Scalar>>; };
// Use the algebraic multi-grid linear solver for this problem
template<class TypeTag>
struct LinearSolverSplice<TypeTag, TTag::Co2InjectionBaseProblem> { using type = TTag::ParallelAmgLinearSolver; };
} // namespace Opm::Properties
namespace Opm::Parameters {
struct FluidSystemNumPressure { static constexpr unsigned value = 100; };
struct FluidSystemNumTemperature { static constexpr unsigned value = 100; };
template<class Scalar>
struct FluidSystemPressureHigh { static constexpr Scalar value = 4e7; };
template<class Scalar>
struct FluidSystemPressureLow { static constexpr Scalar value = 3e7; };
template<class Scalar>
struct FluidSystemTemperatureHigh { static constexpr Scalar value = 500.0; };
template<class Scalar>
struct FluidSystemTemperatureLow { static constexpr Scalar value = 290.0; };
template<class Scalar>
struct MaxDepth { static constexpr Scalar value = 2500.0; };
struct SimulationName { static constexpr auto value = "co2injection"; };
template<class Scalar>
struct Temperature { static constexpr Scalar value = 293.15; };
} // namespace Opm::Parameters
namespace Opm {
double Co2InjectionTolerance = 1e-8;
/*!
* \ingroup TestProblems
*
* \brief Problem where \f$CO_2\f$ is injected under a low permeable
* layer at a depth of 2700m.
*
* The domain is sized 60m times 40m and consists of two layers, one
* which is moderately permeable (\f$K = 10^{-12}\;m^2\f$) for \f$ y >
* 22\; m\f$ and one with a lower intrinsic permeablility (\f$
* K=10^{-13}\;m^2\f$) in the rest of the domain.
*
* \f$CO_2\f$ gets injected by means of a forced-flow boundary
* condition into water-filled aquifer, which is situated 2700m below
* sea level, at the lower-right boundary (\f$5m<y<15m\f$) and
* migrates upwards due to buoyancy. It accumulates and eventually
* enters the lower permeable aquitard.
*
* The boundary conditions applied by this problem are no-flow
* conditions on the top bottom and right boundaries and a free-flow
* boundary condition on the left. For the free-flow condition,
* hydrostatic pressure is assumed.
*/
template <class TypeTag>
class Co2InjectionProblem : public GetPropType<TypeTag, Properties::BaseProblem>
{
using ParentType = GetPropType<TypeTag, Properties::BaseProblem>;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using Evaluation = GetPropType<TypeTag, Properties::Evaluation>;
using GridView = GetPropType<TypeTag, Properties::GridView>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
enum { dim = GridView::dimension };
enum { dimWorld = GridView::dimensionworld };
// copy some indices for convenience
using Indices = GetPropType<TypeTag, Properties::Indices>;
enum { numPhases = FluidSystem::numPhases };
enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
enum { liquidPhaseIdx = FluidSystem::liquidPhaseIdx };
enum { CO2Idx = FluidSystem::CO2Idx };
enum { BrineIdx = FluidSystem::BrineIdx };
enum { conti0EqIdx = Indices::conti0EqIdx };
enum { contiCO2EqIdx = conti0EqIdx + CO2Idx };
using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
using RateVector = GetPropType<TypeTag, Properties::RateVector>;
using BoundaryRateVector = GetPropType<TypeTag, Properties::BoundaryRateVector>;
using MaterialLaw = GetPropType<TypeTag, Properties::MaterialLaw>;
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
using Model = GetPropType<TypeTag, Properties::Model>;
using MaterialLawParams = GetPropType<TypeTag, Properties::MaterialLawParams>;
using ThermalConductionLaw = GetPropType<TypeTag, Properties::ThermalConductionLaw>;
using SolidEnergyLawParams = GetPropType<TypeTag, Properties::SolidEnergyLawParams>;
using ThermalConductionLawParams = typename ThermalConductionLaw::Params;
using Toolbox = Opm::MathToolbox<Evaluation>;
using CoordScalar = typename GridView::ctype;
using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
public:
/*!
* \copydoc Doxygen::defaultProblemConstructor
*/
Co2InjectionProblem(Simulator& simulator)
: ParentType(simulator)
{ }
/*!
* \copydoc FvBaseProblem::finishInit
*/
void finishInit()
{
ParentType::finishInit();
eps_ = 1e-6;
temperatureLow_ = Parameters::Get<Parameters::FluidSystemTemperatureLow<Scalar>>();
temperatureHigh_ = Parameters::Get<Parameters::FluidSystemTemperatureHigh<Scalar>>();
nTemperature_ = Parameters::Get<Parameters::FluidSystemNumTemperature>();
pressureLow_ = Parameters::Get<Parameters::FluidSystemPressureLow<Scalar>>();
pressureHigh_ = Parameters::Get<Parameters::FluidSystemPressureHigh<Scalar>>();
nPressure_ = Parameters::Get<Parameters::FluidSystemNumPressure>();
maxDepth_ = Parameters::Get<Parameters::MaxDepth<Scalar>>();
temperature_ = Parameters::Get<Parameters::Temperature<Scalar>>();
// initialize the tables of the fluid system
// FluidSystem::init();
FluidSystem::init(/*Tmin=*/temperatureLow_,
/*Tmax=*/temperatureHigh_,
/*nT=*/nTemperature_,
/*pmin=*/pressureLow_,
/*pmax=*/pressureHigh_,
/*np=*/nPressure_);
fineLayerBottom_ = 22.0;
// intrinsic permeabilities
fineK_ = this->toDimMatrix_(1e-13);
coarseK_ = this->toDimMatrix_(1e-12);
// porosities
finePorosity_ = 0.3;
coarsePorosity_ = 0.3;
// residual saturations
fineMaterialParams_.setResidualSaturation(liquidPhaseIdx, 0.2);
fineMaterialParams_.setResidualSaturation(gasPhaseIdx, 0.0);
coarseMaterialParams_.setResidualSaturation(liquidPhaseIdx, 0.2);
coarseMaterialParams_.setResidualSaturation(gasPhaseIdx, 0.0);
// parameters for the Brooks-Corey law
fineMaterialParams_.setEntryPressure(1e4);
coarseMaterialParams_.setEntryPressure(5e3);
fineMaterialParams_.setLambda(2.0);
coarseMaterialParams_.setLambda(2.0);
fineMaterialParams_.finalize();
coarseMaterialParams_.finalize();
// parameters for the somerton law thermal conduction
computeThermalCondParams_(fineThermalCondParams_, finePorosity_);
computeThermalCondParams_(coarseThermalCondParams_, coarsePorosity_);
// assume constant heat capacity and granite
solidEnergyLawParams_.setSolidHeatCapacity(790.0 // specific heat capacity of granite [J / (kg K)]
* 2700.0); // density of granite [kg/m^3]
solidEnergyLawParams_.finalize();
}
/*!
* \copydoc FvBaseMultiPhaseProblem::registerParameters
*/
static void registerParameters()
{
ParentType::registerParameters();
Parameters::Register<Parameters::FluidSystemTemperatureLow<Scalar>>
("The lower temperature [K] for tabulation of the fluid system");
Parameters::Register<Parameters::FluidSystemTemperatureHigh<Scalar>>
("The upper temperature [K] for tabulation of the fluid system");
Parameters::Register<Parameters::FluidSystemNumTemperature>
("The number of intervals between the lower and upper temperature");
Parameters::Register<Parameters::FluidSystemPressureLow<Scalar>>
("The lower pressure [Pa] for tabulation of the fluid system");
Parameters::Register<Parameters::FluidSystemPressureHigh<Scalar>>
("The upper pressure [Pa] for tabulation of the fluid system");
Parameters::Register<Parameters::FluidSystemNumPressure>
("The number of intervals between the lower and upper pressure");
Parameters::Register<Parameters::Temperature<Scalar>>
("The temperature [K] in the reservoir");
Parameters::Register<Parameters::MaxDepth<Scalar>>
("The maximum depth [m] of the reservoir");
Parameters::Register<Parameters::SimulationName>
("The name of the simulation used for the output files");
Parameters::SetDefault<Parameters::GridFile>("data/co2injection.dgf");
Parameters::SetDefault<Parameters::EndTime<Scalar>>(1e4);
Parameters::SetDefault<Parameters::InitialTimeStepSize<Scalar>>(250);
Parameters::SetDefault<Parameters::NewtonTolerance<Scalar>>(Scalar{Co2InjectionTolerance});
Parameters::SetDefault<Parameters::EnableGravity>(true);
}
/*!
* \name Problem parameters
*/
//! \{
/*!
* \copydoc FvBaseProblem::name
*/
std::string name() const
{
std::ostringstream oss;
oss << Parameters::Get<Parameters::SimulationName>()
<< "_" << Model::name();
if (getPropValue<TypeTag, Properties::EnableEnergy>())
oss << "_ni";
oss << "_" << Model::discretizationName();
return oss.str();
}
/*!
* \copydoc FvBaseProblem::endTimeStep
*/
void endTimeStep()
{
#ifndef NDEBUG
Scalar tol = this->model().newtonMethod().tolerance()*1e5;
this->model().checkConservativeness(tol);
// Calculate storage terms
PrimaryVariables storageL, storageG;
this->model().globalPhaseStorage(storageL, /*phaseIdx=*/0);
this->model().globalPhaseStorage(storageG, /*phaseIdx=*/1);
// Write mass balance information for rank 0
if (this->gridView().comm().rank() == 0) {
std::cout << "Storage: liquid=[" << storageL << "]"
<< " gas=[" << storageG << "]\n" << std::flush;
}
#endif // NDEBUG
}
/*!
* \copydoc FvBaseMultiPhaseProblem::temperature
*/
template <class Context>
Scalar temperature(const Context& context, unsigned spaceIdx, unsigned timeIdx) const
{
const auto& pos = context.pos(spaceIdx, timeIdx);
if (inHighTemperatureRegion_(pos))
return temperature_ + 100;
return temperature_;
}
/*!
* \copydoc FvBaseMultiPhaseProblem::intrinsicPermeability
*/
template <class Context>
const DimMatrix& intrinsicPermeability(const Context& context, unsigned spaceIdx,
unsigned timeIdx) const
{
const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
if (isFineMaterial_(pos))
return fineK_;
return coarseK_;
}
/*!
* \copydoc FvBaseMultiPhaseProblem::porosity
*/
template <class Context>
Scalar porosity(const Context& context, unsigned spaceIdx, unsigned timeIdx) const
{
const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
if (isFineMaterial_(pos))
return finePorosity_;
return coarsePorosity_;
}
/*!
* \copydoc FvBaseMultiPhaseProblem::materialLawParams
*/
template <class Context>
const MaterialLawParams& materialLawParams(const Context& context,
unsigned spaceIdx, unsigned timeIdx) const
{
const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
if (isFineMaterial_(pos))
return fineMaterialParams_;
return coarseMaterialParams_;
}
/*!
* \brief Return the parameters for the heat storage law of the rock
*
* In this case, we assume the rock-matrix to be granite.
*/
template <class Context>
const SolidEnergyLawParams&
solidEnergyLawParams(const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ return solidEnergyLawParams_; }
/*!
* \copydoc FvBaseMultiPhaseProblem::thermalConductionParams
*/
template <class Context>
const ThermalConductionLawParams &
thermalConductionLawParams(const Context& context,
unsigned spaceIdx,
unsigned timeIdx) const
{
const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
if (isFineMaterial_(pos))
return fineThermalCondParams_;
return coarseThermalCondParams_;
}
//! \}
/*!
* \name Boundary conditions
*/
//! \{
/*!
* \copydoc FvBaseProblem::boundary
*/
template <class Context>
void boundary(BoundaryRateVector& values, const Context& context,
unsigned spaceIdx, unsigned timeIdx) const
{
const auto& pos = context.pos(spaceIdx, timeIdx);
if (onLeftBoundary_(pos)) {
Opm::CompositionalFluidState<Scalar, FluidSystem> fs;
initialFluidState_(fs, context, spaceIdx, timeIdx);
fs.checkDefined();
// impose an freeflow boundary condition
values.setFreeFlow(context, spaceIdx, timeIdx, fs);
}
else if (onInlet_(pos)) {
RateVector massRate(0.0);
massRate[contiCO2EqIdx] = -1e-3; // [kg/(m^3 s)]
using FluidState = Opm::ImmiscibleFluidState<Scalar, FluidSystem>;
FluidState fs;
fs.setSaturation(gasPhaseIdx, 1.0);
const auto& pg =
context.intensiveQuantities(spaceIdx, timeIdx).fluidState().pressure(gasPhaseIdx);
fs.setPressure(gasPhaseIdx, Toolbox::value(pg));
fs.setTemperature(temperature(context, spaceIdx, timeIdx));
typename FluidSystem::template ParameterCache<Scalar> paramCache;
paramCache.updatePhase(fs, gasPhaseIdx);
Scalar h = FluidSystem::template enthalpy<FluidState, Scalar>(fs, paramCache, gasPhaseIdx);
// impose an forced inflow boundary condition for pure CO2
values.setMassRate(massRate);
values.setEnthalpyRate(massRate[contiCO2EqIdx] * h);
}
else
// no flow on top and bottom
values.setNoFlow();
}
// \}
/*!
* \name Volumetric terms
*/
//! \{
/*!
* \copydoc FvBaseProblem::initial
*/
template <class Context>
void initial(PrimaryVariables& values, const Context& context, unsigned spaceIdx,
unsigned timeIdx) const
{
Opm::CompositionalFluidState<Scalar, FluidSystem> fs;
initialFluidState_(fs, context, spaceIdx, timeIdx);
// const auto& matParams = this->materialLawParams(context, spaceIdx,
// timeIdx);
// values.assignMassConservative(fs, matParams, /*inEquilibrium=*/true);
values.assignNaive(fs);
}
/*!
* \copydoc FvBaseProblem::source
*
* For this problem, the source term of all components is 0
* everywhere.
*/
template <class Context>
void source(RateVector& rate,
const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ rate = Scalar(0.0); }
//! \}
private:
template <class Context, class FluidState>
void initialFluidState_(FluidState& fs,
const Context& context,
unsigned spaceIdx,
unsigned timeIdx) const
{
const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
//////
// set temperature
//////
fs.setTemperature(temperature(context, spaceIdx, timeIdx));
//////
// set saturations
//////
fs.setSaturation(FluidSystem::liquidPhaseIdx, 1.0);
fs.setSaturation(FluidSystem::gasPhaseIdx, 0.0);
//////
// set pressures
//////
Scalar densityL = FluidSystem::Brine::liquidDensity(temperature_, Scalar(1e5));
Scalar depth = maxDepth_ - pos[dim - 1];
Scalar pl = 1e5 - densityL * this->gravity()[dim - 1] * depth;
Scalar pC[numPhases];
const auto& matParams = this->materialLawParams(context, spaceIdx, timeIdx);
MaterialLaw::capillaryPressures(pC, matParams, fs);
fs.setPressure(liquidPhaseIdx, pl + (pC[liquidPhaseIdx] - pC[liquidPhaseIdx]));
fs.setPressure(gasPhaseIdx, pl + (pC[gasPhaseIdx] - pC[liquidPhaseIdx]));
//////
// set composition of the liquid phase
//////
fs.setMoleFraction(liquidPhaseIdx, CO2Idx, 0.005);
fs.setMoleFraction(liquidPhaseIdx, BrineIdx,
1.0 - fs.moleFraction(liquidPhaseIdx, CO2Idx));
typename FluidSystem::template ParameterCache<Scalar> paramCache;
using CFRP = Opm::ComputeFromReferencePhase<Scalar, FluidSystem>;
CFRP::solve(fs, paramCache,
/*refPhaseIdx=*/liquidPhaseIdx,
/*setViscosity=*/true,
/*setEnthalpy=*/true);
}
bool onLeftBoundary_(const GlobalPosition& pos) const
{ return pos[0] < eps_; }
bool onRightBoundary_(const GlobalPosition& pos) const
{ return pos[0] > this->boundingBoxMax()[0] - eps_; }
bool onInlet_(const GlobalPosition& pos) const
{ return onRightBoundary_(pos) && (5 < pos[1]) && (pos[1] < 15); }
bool inHighTemperatureRegion_(const GlobalPosition& pos) const
{ return (pos[0] > 20) && (pos[0] < 30) && (pos[1] > 5) && (pos[1] < 35); }
void computeThermalCondParams_(ThermalConductionLawParams& params, Scalar poro)
{
Scalar lambdaWater = 0.6;
Scalar lambdaGranite = 2.8;
Scalar lambdaWet = std::pow(lambdaGranite, (1 - poro))
* std::pow(lambdaWater, poro);
Scalar lambdaDry = std::pow(lambdaGranite, (1 - poro));
params.setFullySaturatedLambda(gasPhaseIdx, lambdaDry);
params.setFullySaturatedLambda(liquidPhaseIdx, lambdaWet);
params.setVacuumLambda(lambdaDry);
}
bool isFineMaterial_(const GlobalPosition& pos) const
{ return pos[dim - 1] > fineLayerBottom_; }
DimMatrix fineK_;
DimMatrix coarseK_;
Scalar fineLayerBottom_;
Scalar finePorosity_;
Scalar coarsePorosity_;
MaterialLawParams fineMaterialParams_;
MaterialLawParams coarseMaterialParams_;
ThermalConductionLawParams fineThermalCondParams_;
ThermalConductionLawParams coarseThermalCondParams_;
SolidEnergyLawParams solidEnergyLawParams_;
Scalar temperature_;
Scalar maxDepth_;
Scalar eps_;
unsigned nTemperature_;
unsigned nPressure_;
Scalar pressureLow_, pressureHigh_;
Scalar temperatureLow_, temperatureHigh_;
};
} // namespace Opm
#endif

View File

@ -0,0 +1,520 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \copydoc Opm::co2ptflashproblem
*/
#ifndef OPM_CO2PTFLASH_PROBLEM_HH
#define OPM_CO2PTFLASH_PROBLEM_HH
#include <opm/common/Exceptions.hpp>
#include <opm/material/components/SimpleCO2.hpp>
#include <opm/material/components/C10.hpp>
#include <opm/material/components/C1.hpp>
#include <opm/material/fluidmatrixinteractions/RegularizedBrooksCorey.hpp>
#include <opm/material/fluidmatrixinteractions/BrooksCorey.hpp>
#include <opm/material/constraintsolvers/PTFlash.hpp>
#include <opm/material/fluidsystems/GenericOilGasFluidSystem.hpp>
#include <opm/material/common/Valgrind.hpp>
#include <opm/models/immiscible/immisciblemodel.hh>
#include <opm/models/discretization/ecfv/ecfvdiscretization.hh>
#include <opm/models/ptflash/flashmodel.hh>
#include <opm/models/io/structuredgridvanguard.hh>
#include <opm/models/utils/propertysystem.hh>
#include <opm/models/utils/start.hh>
#include <opm/simulators/linalg/parallelistlbackend.hh>
#include <opm/simulators/linalg/parallelbicgstabbackend.hh>
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/io/file/dgfparser/dgfyasp.hh>
#include <dune/common/version.hh>
#include <dune/common/fvector.hh>
#include <dune/common/fmatrix.hh>
#include <sstream>
#include <string>
namespace Opm {
template <class TypeTag>
class CO2PTProblem;
} // namespace Opm */
namespace Opm::Properties {
namespace TTag {
struct CO2PTBaseProblem {};
} // end namespace TTag
template <class TypeTag, class MyTypeTag>
struct NumComp { using type = UndefinedProperty; };
template <class TypeTag>
struct NumComp<TypeTag, TTag::CO2PTBaseProblem> {
static constexpr int value = 3;
};
// Set the grid type: --->2D
template <class TypeTag>
struct Grid<TypeTag, TTag::CO2PTBaseProblem> { using type = Dune::YaspGrid</*dim=*/2>; };
// Set the problem property
template <class TypeTag>
struct Problem<TypeTag, TTag::CO2PTBaseProblem>
{ using type = Opm::CO2PTProblem<TypeTag>; };
// Set flash solver
template <class TypeTag>
struct FlashSolver<TypeTag, TTag::CO2PTBaseProblem> {
private:
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
using Evaluation = GetPropType<TypeTag, Properties::Evaluation>;
public:
using type = Opm::PTFlash<Scalar, FluidSystem>;
};
// Set fluid configuration
template <class TypeTag>
struct FluidSystem<TypeTag, TTag::CO2PTBaseProblem>
{
private:
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
static constexpr int num_comp = getPropValue<TypeTag, Properties::NumComp>();
public:
using type = Opm::GenericOilGasFluidSystem<Scalar, num_comp>;
};
// Set the material Law
template <class TypeTag>
struct MaterialLaw<TypeTag, TTag::CO2PTBaseProblem> {
private:
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using Traits = Opm::TwoPhaseMaterialTraits<Scalar,
// /*wettingPhaseIdx=*/FluidSystem::waterPhaseIdx, // TODO
/*nonWettingPhaseIdx=*/FluidSystem::oilPhaseIdx,
/*gasPhaseIdx=*/FluidSystem::gasPhaseIdx>;
// define the material law which is parameterized by effective saturation
using EffMaterialLaw = Opm::NullMaterial<Traits>;
//using EffMaterialLaw = Opm::BrooksCorey<Traits>;
public:
using type = EffMaterialLaw;
};
// mesh grid
template <class TypeTag>
struct Vanguard<TypeTag, TTag::CO2PTBaseProblem> {
using type = Opm::StructuredGridVanguard<TypeTag>;
};
template <class TypeTag>
struct EnableEnergy<TypeTag, TTag::CO2PTBaseProblem> {
static constexpr bool value = false;
};
} // namespace Opm::Properties
namespace Opm::Parameters {
// this is kinds of telling the report step length
template<class Scalar>
struct EpisodeLength { static constexpr Scalar value = 0.1 * 60. * 60.; };
template<class Scalar>
struct Initialpressure { static constexpr Scalar value = 75e5; };
struct SimulationName { static constexpr auto value = "co2_ptflash"; };
// set the defaults for the problem specific properties
template<class Scalar>
struct Temperature { static constexpr Scalar value = 423.25; };
} // namespace Opm::Parameters
namespace Opm {
/*!
* \ingroup TestProblems
*
* \brief 3 component simple testproblem with ["CO2", "C1", "C10"]
*
*/
template <class TypeTag>
class CO2PTProblem : public GetPropType<TypeTag, Properties::BaseProblem>
{
using ParentType = GetPropType<TypeTag, Properties::BaseProblem>;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using Evaluation = GetPropType<TypeTag, Properties::Evaluation>;
using GridView = GetPropType<TypeTag, Properties::GridView>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
enum { dim = GridView::dimension };
enum { dimWorld = GridView::dimensionworld };
using Indices = GetPropType<TypeTag, Properties::Indices>;
using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
using RateVector = GetPropType<TypeTag, Properties::RateVector>;
using BoundaryRateVector = GetPropType<TypeTag, Properties::BoundaryRateVector>;
using MaterialLaw = GetPropType<TypeTag, Properties::MaterialLaw>;
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
using Model = GetPropType<TypeTag, Properties::Model>;
using MaterialLawParams = GetPropType<TypeTag, Properties::MaterialLawParams>;
using Toolbox = Opm::MathToolbox<Evaluation>;
using CoordScalar = typename GridView::ctype;
enum { numPhases = FluidSystem::numPhases };
enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
enum { conti0EqIdx = Indices::conti0EqIdx };
enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
enum { enableEnergy = getPropValue<TypeTag, Properties::EnableEnergy>() };
enum { enableDiffusion = getPropValue<TypeTag, Properties::EnableDiffusion>() };
using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
using DimVector = Dune::FieldVector<Scalar, dimWorld>;
using ComponentVector = Dune::FieldVector<Evaluation, numComponents>;
using FlashSolver = GetPropType<TypeTag, Properties::FlashSolver>;
public:
using FluidState = Opm::CompositionalFluidState<Evaluation, FluidSystem, enableEnergy>;
/*!
* \copydoc Doxygen::defaultProblemConstructor
*/
explicit CO2PTProblem(Simulator& simulator)
: ParentType(simulator)
{
const Scalar epi_len = Parameters::Get<Parameters::EpisodeLength<Scalar>>();
simulator.setEpisodeLength(epi_len);
FluidSystem::init();
using CompParm = typename FluidSystem::ComponentParam;
using CO2 = Opm::SimpleCO2<Scalar>;
using C1 = Opm::C1<Scalar>;
using C10 = Opm::C10<Scalar>;
FluidSystem::addComponent(CompParm {CO2::name(), CO2::molarMass(), CO2::criticalTemperature(),
CO2::criticalPressure(), CO2::criticalVolume(), CO2::acentricFactor()});
FluidSystem::addComponent(CompParm {C1::name(), C1::molarMass(), C1::criticalTemperature(),
C1::criticalPressure(), C1::criticalVolume(), C1::acentricFactor()});
FluidSystem::addComponent(CompParm{C10::name(), C10::molarMass(), C10::criticalTemperature(),
C10::criticalPressure(), C10::criticalVolume(), C10::acentricFactor()});
// FluidSystem::add
}
void initPetrophysics()
{
temperature_ = Parameters::Get<Parameters::Temperature<Scalar>>();
K_ = this->toDimMatrix_(9.869232667160131e-14);
porosity_ = 0.1;
}
template <class Context>
const DimVector&
gravity([[maybe_unused]]const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{
return gravity();
}
const DimVector& gravity() const
{
return gravity_;
}
/*!
* \copydoc FvBaseProblem::finishInit
*/
void finishInit()
{
ParentType::finishInit();
// initialize fixed parameters; temperature, permeability, porosity
initPetrophysics();
}
/*!
* \copydoc co2ptflashproblem::registerParameters
*/
static void registerParameters()
{
ParentType::registerParameters();
Parameters::Register<Parameters::Temperature<Scalar>>
("The temperature [K] in the reservoir");
Parameters::Register<Parameters::Initialpressure<Scalar>>
("The initial pressure [Pa s] in the reservoir");
Parameters::Register<Parameters::SimulationName>
("The name of the simulation used for the output files");
Parameters::Register<Parameters::EpisodeLength<Scalar>>
("Time interval [s] for episode length");
Parameters::SetDefault<Parameters::CellsX>(30);
Parameters::SetDefault<Parameters::DomainSizeX<Scalar>>(300.0);
if constexpr (dim > 1) {
Parameters::SetDefault<Parameters::CellsY>(1);
Parameters::SetDefault<Parameters::DomainSizeY<Scalar>>(1.0);
}
if constexpr (dim == 3) {
Parameters::SetDefault<Parameters::CellsZ>(1);
Parameters::SetDefault<Parameters::DomainSizeZ<Scalar>>(1.0);
}
Parameters::SetDefault<Parameters::EndTime<Scalar>>(60. * 60.);
Parameters::SetDefault<Parameters::InitialTimeStepSize<Scalar>>(0.1 * 60. * 60.);
Parameters::SetDefault<Parameters::NewtonMaxIterations>(30);
Parameters::SetDefault<Parameters::NewtonTargetIterations>(6);
Parameters::SetDefault<Parameters::NewtonTolerance<Scalar>>(1e-3);
Parameters::SetDefault<Parameters::VtkWriteFilterVelocities>(true);
Parameters::SetDefault<Parameters::VtkWriteFugacityCoeffs>(true);
Parameters::SetDefault<Parameters::VtkWritePotentialGradients>(true);
Parameters::SetDefault<Parameters::VtkWriteTotalMassFractions>(true);
Parameters::SetDefault<Parameters::VtkWriteTotalMoleFractions>(true);
Parameters::SetDefault<Parameters::VtkWriteEquilibriumConstants>(true);
Parameters::SetDefault<Parameters::VtkWriteLiquidMoleFractions>(true);
Parameters::SetDefault<Parameters::LinearSolverAbsTolerance<Scalar>>(0.0);
Parameters::SetDefault<Parameters::LinearSolverTolerance<Scalar>>(1e-3);
}
/*!
* \copydoc FvBaseProblem::name
*/
std::string name() const
{
std::ostringstream oss;
oss << Parameters::Get<Parameters::SimulationName>();
return oss.str();
}
// This method must be overridden for the simulator to continue with
// a new episode. We just start a new episode with the same length as
// the old one.
void endEpisode()
{
Scalar epi_len = Parameters::Get<Parameters::EpisodeLength<Scalar>>();
this->simulator().startNextEpisode(epi_len);
}
// only write output when episodes change, aka. report steps, and
// include the initial timestep too
bool shouldWriteOutput()
{
return this->simulator().episodeWillBeOver() || (this->simulator().timeStepIndex() == -1);
}
// we don't care about doing restarts from every fifth timestep, it
// will just slow us down
bool shouldWriteRestartFile()
{
return false;
}
/*!
* \copydoc FvBaseProblem::endTimeStep
*/
void endTimeStep()
{
Scalar tol = this->model().newtonMethod().tolerance() * 1e5;
this->model().checkConservativeness(tol);
// Calculate storage terms
PrimaryVariables storageO, storageW;
this->model().globalPhaseStorage(storageO, oilPhaseIdx);
// Calculate storage terms
PrimaryVariables storageL, storageG;
this->model().globalPhaseStorage(storageL, /*phaseIdx=*/0);
this->model().globalPhaseStorage(storageG, /*phaseIdx=*/1);
// Write mass balance information for rank 0
// if (this->gridView().comm().rank() == 0) {
// std::cout << "Storage: liquid=[" << storageL << "]"
// << " gas=[" << storageG << "]\n" << std::flush;
// }
}
/*!
* \copydoc FvBaseProblem::initial
*/
template <class Context>
void initial(PrimaryVariables& values, const Context& context, unsigned spaceIdx, unsigned timeIdx) const
{
Opm::CompositionalFluidState<Evaluation, FluidSystem> fs;
initialFluidState(fs, context, spaceIdx, timeIdx);
values.assignNaive(fs);
}
// Constant temperature
template <class Context>
Scalar temperature([[maybe_unused]] const Context& context, [[maybe_unused]] unsigned spaceIdx, [[maybe_unused]] unsigned timeIdx) const
{
return temperature_;
}
// Constant permeability
template <class Context>
const DimMatrix& intrinsicPermeability([[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{
return K_;
}
// Constant porosity
template <class Context>
Scalar porosity([[maybe_unused]] const Context& context, [[maybe_unused]] unsigned spaceIdx, [[maybe_unused]] unsigned timeIdx) const
{
int spatialIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
int inj = 0;
int prod = Parameters::Get<Parameters::CellsX>() - 1;
if (spatialIdx == inj || spatialIdx == prod) {
return 1.0;
} else {
return porosity_;
}
}
/*!
* \copydoc FvBaseMultiPhaseProblem::materialLawParams
*/
template <class Context>
const MaterialLawParams& materialLawParams([[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{
return this->mat_;
}
// No flow (introduce fake wells instead)
template <class Context>
void boundary(BoundaryRateVector& values,
const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ values.setNoFlow(); }
// No source terms
template <class Context>
void source(RateVector& source_rate,
[[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{
source_rate = Scalar(0.0);
}
private:
/*!
* \copydoc FvBaseProblem::initial
*/
template <class FluidState, class Context>
void initialFluidState(FluidState& fs, const Context& context, unsigned spaceIdx, unsigned timeIdx) const
{
// z0 = [0.5, 0.3, 0.2]
// zi = [0.99, 0.01-1e-3, 1e-3]
// p0 = 75e5
// T0 = 423.25
int inj = 0;
int prod = Parameters::Get<Parameters::CellsX>() - 1;
int spatialIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
ComponentVector comp;
comp[0] = Evaluation::createVariable(0.5, 1);
comp[1] = Evaluation::createVariable(0.3, 2);
comp[2] = 1. - comp[0] - comp[1];
if (spatialIdx == inj) {
comp[0] = Evaluation::createVariable(0.99, 1);
comp[1] = Evaluation::createVariable(0.01 - 1e-3, 2);
comp[2] = 1. - comp[0] - comp[1];
}
ComponentVector sat;
sat[0] = 1.0;
sat[1] = 1.0 - sat[0];
Scalar p0 = Parameters::Get<Parameters::Initialpressure<Scalar>>();
//\Note, for an AD variable, if we multiply it with 2, the derivative will also be scalced with 2,
//\Note, so we should not do it.
if (spatialIdx == inj) {
p0 *= 2.0;
}
if (spatialIdx == prod) {
p0 *= 0.5;
}
Evaluation p_init = Evaluation::createVariable(p0, 0);
fs.setPressure(FluidSystem::oilPhaseIdx, p_init);
fs.setPressure(FluidSystem::gasPhaseIdx, p_init);
for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
fs.setMoleFraction(FluidSystem::oilPhaseIdx, compIdx, comp[compIdx]);
fs.setMoleFraction(FluidSystem::gasPhaseIdx, compIdx, comp[compIdx]);
}
// It is used here only for calculate the z
fs.setSaturation(FluidSystem::oilPhaseIdx, sat[0]);
fs.setSaturation(FluidSystem::gasPhaseIdx, sat[1]);
fs.setTemperature(temperature_);
// ParameterCache paramCache;
{
typename FluidSystem::template ParameterCache<Evaluation> paramCache;
paramCache.updatePhase(fs, FluidSystem::oilPhaseIdx);
paramCache.updatePhase(fs, FluidSystem::gasPhaseIdx);
fs.setDensity(FluidSystem::oilPhaseIdx, FluidSystem::density(fs, paramCache, FluidSystem::oilPhaseIdx));
fs.setDensity(FluidSystem::gasPhaseIdx, FluidSystem::density(fs, paramCache, FluidSystem::gasPhaseIdx));
fs.setViscosity(FluidSystem::oilPhaseIdx, FluidSystem::viscosity(fs, paramCache, FluidSystem::oilPhaseIdx));
fs.setViscosity(FluidSystem::gasPhaseIdx, FluidSystem::viscosity(fs, paramCache, FluidSystem::gasPhaseIdx));
}
// Set initial K and L
for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
const Evaluation Ktmp = fs.wilsonK_(compIdx);
fs.setKvalue(compIdx, Ktmp);
}
const Evaluation& Ltmp = -1.0;
fs.setLvalue(Ltmp);
}
DimMatrix K_;
Scalar porosity_;
Scalar temperature_;
MaterialLawParams mat_;
DimVector gravity_;
};
} // namespace Opm
#endif

View File

@ -0,0 +1,642 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \copydoc Opm::CuvetteProblem
*/
#ifndef EWOMS_CUVETTE_PROBLEM_HH
#define EWOMS_CUVETTE_PROBLEM_HH
#include <opm/models/pvs/pvsproperties.hh>
#include <opm/material/fluidstates/CompositionalFluidState.hpp>
#include <opm/material/fluidstates/ImmiscibleFluidState.hpp>
#include <opm/material/fluidsystems/H2OAirMesityleneFluidSystem.hpp>
#include <opm/material/fluidmatrixinteractions/ThreePhaseParkerVanGenuchten.hpp>
#include <opm/material/fluidmatrixinteractions/LinearMaterial.hpp>
#include <opm/material/thermal/ConstantSolidHeatCapLaw.hpp>
#include <opm/material/thermal/SomertonThermalConductionLaw.hpp>
#include <opm/material/constraintsolvers/MiscibleMultiPhaseComposition.hpp>
#include <opm/material/fluidmatrixinteractions/MaterialTraits.hpp>
#include <opm/material/common/Valgrind.hpp>
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/io/file/dgfparser/dgfyasp.hh>
#include <dune/common/version.hh>
#include <dune/common/fvector.hh>
#include <dune/common/fmatrix.hh>
#include <string>
namespace Opm {
template <class TypeTag>
class CuvetteProblem;
}
namespace Opm::Properties {
// create a new type tag for the cuvette steam injection problem
namespace TTag {
struct CuvetteBaseProblem {};
}
// Set the grid type
template<class TypeTag>
struct Grid<TypeTag, TTag::CuvetteBaseProblem> { using type = Dune::YaspGrid<2>; };
// Set the problem property
template<class TypeTag>
struct Problem<TypeTag, TTag::CuvetteBaseProblem> { using type = Opm::CuvetteProblem<TypeTag>; };
// Set the fluid system
template<class TypeTag>
struct FluidSystem<TypeTag, TTag::CuvetteBaseProblem>
{ using type = Opm::H2OAirMesityleneFluidSystem<GetPropType<TypeTag, Properties::Scalar>>; };
// Set the material Law
template<class TypeTag>
struct MaterialLaw<TypeTag, TTag::CuvetteBaseProblem>
{
private:
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
using Traits = Opm::ThreePhaseMaterialTraits<
Scalar,
/*wettingPhaseIdx=*/FluidSystem::waterPhaseIdx,
/*nonWettingPhaseIdx=*/FluidSystem::naplPhaseIdx,
/*gasPhaseIdx=*/FluidSystem::gasPhaseIdx>;
public:
using type = Opm::ThreePhaseParkerVanGenuchten<Traits>;
};
// set the energy storage law for the solid phase
template<class TypeTag>
struct SolidEnergyLaw<TypeTag, TTag::CuvetteBaseProblem>
{ using type = Opm::ConstantSolidHeatCapLaw<GetPropType<TypeTag, Properties::Scalar>>; };
// Set the thermal conduction law
template<class TypeTag>
struct ThermalConductionLaw<TypeTag, TTag::CuvetteBaseProblem>
{
private:
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
public:
// define the material law parameterized by absolute saturations
using type = Opm::SomertonThermalConductionLaw<FluidSystem, Scalar>;
};
} // namespace Opm::Properties
namespace Opm {
/*!
* \ingroup TestProblems
*
* \brief Non-isothermal three-phase gas injection problem where a hot gas
* is injected into a unsaturated porous medium with a residually
* trapped NAPL contamination.
*
* The domain is a quasi-two-dimensional container (cuvette). Its
* dimensions are 1.5 m x 0.74 m. The top and bottom boundaries are
* closed, the right boundary is a free-flow boundary allowing fluids
* to escape. From the left, an injection of a hot water-air mixture
* is injected. The set-up is aimed at remediating an initial NAPL
* (Non-Aquoeus Phase Liquid) contamination in the domain. The
* contamination is initially placed partly into the ambient coarse
* sand and partly into a fine sand lens.
*
* This simulation can be varied through assigning different boundary conditions
* at the left boundary as described in Class (2001):
* Theorie und numerische Modellierung nichtisothermer Mehrphasenprozesse in
* NAPL-kontaminierten poroesen Medien, Dissertation, Eigenverlag des Instituts
* fuer Wasserbau
*
* To see the basic effect and the differences to scenarios with pure
* steam or pure air injection, it is sufficient to simulate this
* problem to about 2-3 hours simulation time. Complete remediation
* of the domain requires much longer (about 10 days simulated time).
*/
template <class TypeTag>
class CuvetteProblem : public GetPropType<TypeTag, Properties::BaseProblem>
{
using ParentType = GetPropType<TypeTag, Properties::BaseProblem>;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using GridView = GetPropType<TypeTag, Properties::GridView>;
using MaterialLaw = GetPropType<TypeTag, Properties::MaterialLaw>;
using MaterialLawParams = GetPropType<TypeTag, Properties::MaterialLawParams>;
using ThermalConductionLawParams = GetPropType<TypeTag, Properties::ThermalConductionLawParams>;
using SolidEnergyLawParams = GetPropType<TypeTag, Properties::SolidEnergyLawParams>;
using EqVector = GetPropType<TypeTag, Properties::EqVector>;
using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
using RateVector = GetPropType<TypeTag, Properties::RateVector>;
using BoundaryRateVector = GetPropType<TypeTag, Properties::BoundaryRateVector>;
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
using Model = GetPropType<TypeTag, Properties::Model>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
// copy some indices for convenience
using Indices = GetPropType<TypeTag, Properties::Indices>;
enum { numPhases = FluidSystem::numPhases };
enum { numComponents = FluidSystem::numComponents };
enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
enum { naplPhaseIdx = FluidSystem::naplPhaseIdx };
enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
enum { H2OIdx = FluidSystem::H2OIdx };
enum { airIdx = FluidSystem::airIdx };
enum { NAPLIdx = FluidSystem::NAPLIdx };
enum { conti0EqIdx = Indices::conti0EqIdx };
// Grid and world dimension
enum { dimWorld = GridView::dimensionworld };
using CoordScalar = typename GridView::ctype;
using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
public:
/*!
* \copydoc Doxygen::defaultProblemConstructor
*/
CuvetteProblem(Simulator& simulator)
: ParentType(simulator)
, eps_(1e-6)
{ }
/*!
* \copydoc FvBaseProblem::finishInit
*/
void finishInit()
{
ParentType::finishInit();
if (Opm::Valgrind::IsRunning())
FluidSystem::init(/*minT=*/283.15, /*maxT=*/500.0, /*nT=*/20,
/*minp=*/0.8e5, /*maxp=*/2e5, /*np=*/10);
else
FluidSystem::init(/*minT=*/283.15, /*maxT=*/500.0, /*nT=*/200,
/*minp=*/0.8e5, /*maxp=*/2e5, /*np=*/100);
// intrinsic permeabilities
fineK_ = this->toDimMatrix_(6.28e-12);
coarseK_ = this->toDimMatrix_(9.14e-10);
// porosities
finePorosity_ = 0.42;
coarsePorosity_ = 0.42;
// parameters for the capillary pressure law
#if 1
// three-phase Parker -- van Genuchten law
fineMaterialParams_.setVgAlpha(0.0005);
coarseMaterialParams_.setVgAlpha(0.005);
fineMaterialParams_.setVgN(4.0);
coarseMaterialParams_.setVgN(4.0);
coarseMaterialParams_.setkrRegardsSnr(true);
fineMaterialParams_.setkrRegardsSnr(true);
// residual saturations
fineMaterialParams_.setSwr(0.1201);
fineMaterialParams_.setSwrx(0.1201);
fineMaterialParams_.setSnr(0.0701);
fineMaterialParams_.setSgr(0.0101);
coarseMaterialParams_.setSwr(0.1201);
coarseMaterialParams_.setSwrx(0.1201);
coarseMaterialParams_.setSnr(0.0701);
coarseMaterialParams_.setSgr(0.0101);
#else
// linear material law
fineMaterialParams_.setPcMinSat(gasPhaseIdx, 0);
fineMaterialParams_.setPcMaxSat(gasPhaseIdx, 0);
fineMaterialParams_.setPcMinSat(naplPhaseIdx, 0);
fineMaterialParams_.setPcMaxSat(naplPhaseIdx, -1000);
fineMaterialParams_.setPcMinSat(waterPhaseIdx, 0);
fineMaterialParams_.setPcMaxSat(waterPhaseIdx, -10000);
coarseMaterialParams_.setPcMinSat(gasPhaseIdx, 0);
coarseMaterialParams_.setPcMaxSat(gasPhaseIdx, 0);
coarseMaterialParams_.setPcMinSat(naplPhaseIdx, 0);
coarseMaterialParams_.setPcMaxSat(naplPhaseIdx, -100);
coarseMaterialParams_.setPcMinSat(waterPhaseIdx, 0);
coarseMaterialParams_.setPcMaxSat(waterPhaseIdx, -1000);
// residual saturations
fineMaterialParams_.setResidSat(waterPhaseIdx, 0.1201);
fineMaterialParams_.setResidSat(naplPhaseIdx, 0.0701);
fineMaterialParams_.setResidSat(gasPhaseIdx, 0.0101);
coarseMaterialParams_.setResidSat(waterPhaseIdx, 0.1201);
coarseMaterialParams_.setResidSat(naplPhaseIdx, 0.0701);
coarseMaterialParams_.setResidSat(gasPhaseIdx, 0.0101);
#endif
fineMaterialParams_.finalize();
coarseMaterialParams_.finalize();
// initialize parameters for the thermal conduction law
computeThermalCondParams_(thermalCondParams_, finePorosity_);
// assume constant volumetric heat capacity and granite
solidEnergyLawParams_.setSolidHeatCapacity(790.0 // specific heat capacity of granite [J / (kg K)]
* 2700.0); // density of granite [kg/m^3]
solidEnergyLawParams_.finalize();
initInjectFluidState_();
}
/*!
* \copydoc FvBaseMultiPhaseProblem::registerParameters
*/
static void registerParameters()
{
ParentType::registerParameters();
Parameters::SetDefault<Parameters::GridFile>("./data/cuvette_11x4.dgf");
Parameters::SetDefault<Parameters::EndTime<Scalar>>(100.0);
Parameters::SetDefault<Parameters::InitialTimeStepSize<Scalar>>(1.0);
Parameters::SetDefault<Parameters::MaxTimeStepSize<Scalar>>(600.0);
Parameters::SetDefault<Parameters::EnableGravity>(true);
}
/*!
* \name Auxiliary methods
*/
//! \{
/*!
* \copydoc FvBaseProblem::shouldWriteRestartFile
*
* This problem writes a restart file after every time step.
*/
bool shouldWriteRestartFile() const
{ return true; }
/*!
* \copydoc FvBaseProblem::name
*/
std::string name() const
{ return std::string("cuvette_") + Model::name(); }
/*!
* \copydoc FvBaseProblem::endTimeStep
*/
void endTimeStep()
{
#ifndef NDEBUG
this->model().checkConservativeness();
// Calculate storage terms
EqVector storage;
this->model().globalStorage(storage);
// Write mass balance information for rank 0
if (this->gridView().comm().rank() == 0) {
std::cout << "Storage: " << storage << std::endl << std::flush;
}
#endif // NDEBUG
}
//! \}
/*!
* \name Soil parameters
*/
//! \{
/*!
* \copydoc FvBaseMultiPhaseProblem::temperature
*/
template <class Context>
Scalar temperature(const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ return 293.15; /* [K] */ }
/*!
* \copydoc FvBaseMultiPhaseProblem::intrinsicPermeability
*/
template <class Context>
const DimMatrix& intrinsicPermeability(const Context& context, unsigned spaceIdx,
unsigned timeIdx) const
{
const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
if (isFineMaterial_(pos))
return fineK_;
return coarseK_;
}
/*!
* \copydoc FvBaseMultiPhaseProblem::porosity
*/
template <class Context>
Scalar porosity(const Context& context, unsigned spaceIdx, unsigned timeIdx) const
{
const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
if (isFineMaterial_(pos))
return finePorosity_;
else
return coarsePorosity_;
}
/*!
* \copydoc FvBaseMultiPhaseProblem::materialLawParams
*/
template <class Context>
const MaterialLawParams& materialLawParams(const Context& context,
unsigned spaceIdx, unsigned timeIdx) const
{
const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
if (isFineMaterial_(pos))
return fineMaterialParams_;
else
return coarseMaterialParams_;
}
/*!
* \copydoc FvBaseMultiPhaseProblem::thermalConductionParams
*/
template <class Context>
const ThermalConductionLawParams &
thermalConductionParams(const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ return thermalCondParams_; }
//! \}
/*!
* \name Boundary conditions
*/
//! \{
/*!
* \copydoc FvBaseProblem::boundary
*/
template <class Context>
void boundary(BoundaryRateVector& values, const Context& context,
unsigned spaceIdx, unsigned timeIdx) const
{
const auto& pos = context.pos(spaceIdx, timeIdx);
if (onRightBoundary_(pos)) {
Opm::CompositionalFluidState<Scalar, FluidSystem> fs;
initialFluidState_(fs, context, spaceIdx, timeIdx);
values.setFreeFlow(context, spaceIdx, timeIdx, fs);
values.setNoFlow();
}
else if (onLeftBoundary_(pos)) {
// injection
RateVector molarRate;
// inject with the same composition as the gas phase of
// the injection fluid state
Scalar molarInjectionRate = 0.3435; // [mol/(m^2 s)]
for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx)
molarRate[conti0EqIdx + compIdx] =
-molarInjectionRate
* injectFluidState_.moleFraction(gasPhaseIdx, compIdx);
// calculate the total mass injection rate [kg / (m^2 s)
Scalar massInjectionRate =
molarInjectionRate
* injectFluidState_.averageMolarMass(gasPhaseIdx);
// set the boundary rate vector [J / (m^2 s)]
values.setMolarRate(molarRate);
values.setEnthalpyRate(-injectFluidState_.enthalpy(gasPhaseIdx) * massInjectionRate);
}
else
values.setNoFlow();
}
//! \}
/*!
* \name Volumetric terms
*/
//! \{
/*!
* \copydoc FvBaseProblem::initial
*/
template <class Context>
void initial(PrimaryVariables& values, const Context& context, unsigned spaceIdx,
unsigned timeIdx) const
{
Opm::CompositionalFluidState<Scalar, FluidSystem> fs;
initialFluidState_(fs, context, spaceIdx, timeIdx);
const auto& matParams = materialLawParams(context, spaceIdx, timeIdx);
values.assignMassConservative(fs, matParams, /*inEquilibrium=*/false);
}
/*!
* \copydoc FvBaseProblem::source
*
* For this problem, the source term of all components is 0
* everywhere.
*/
template <class Context>
void source(RateVector& rate,
const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ rate = Scalar(0.0); }
//! \}
private:
bool onLeftBoundary_(const GlobalPosition& pos) const
{ return pos[0] < eps_; }
bool onRightBoundary_(const GlobalPosition& pos) const
{ return pos[0] > this->boundingBoxMax()[0] - eps_; }
bool onLowerBoundary_(const GlobalPosition& pos) const
{ return pos[1] < eps_; }
bool onUpperBoundary_(const GlobalPosition& pos) const
{ return pos[1] > this->boundingBoxMax()[1] - eps_; }
bool isContaminated_(const GlobalPosition& pos) const
{
return (0.20 <= pos[0]) && (pos[0] <= 0.80) && (0.4 <= pos[1])
&& (pos[1] <= 0.65);
}
bool isFineMaterial_(const GlobalPosition& pos) const
{
if (0.13 <= pos[0] && 1.20 >= pos[0] && 0.32 <= pos[1] && pos[1] <= 0.57)
return true;
else if (pos[1] <= 0.15 && 1.20 <= pos[0])
return true;
else
return false;
}
template <class FluidState, class Context>
void initialFluidState_(FluidState& fs, const Context& context,
unsigned spaceIdx, unsigned timeIdx) const
{
const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
fs.setTemperature(293.0 /*[K]*/);
Scalar pw = 1e5;
if (isContaminated_(pos)) {
fs.setSaturation(waterPhaseIdx, 0.12);
fs.setSaturation(naplPhaseIdx, 0.07);
fs.setSaturation(gasPhaseIdx, 1 - 0.12 - 0.07);
// set the capillary pressures
const auto& matParams = materialLawParams(context, spaceIdx, timeIdx);
Scalar pc[numPhases];
MaterialLaw::capillaryPressures(pc, matParams, fs);
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
fs.setPressure(phaseIdx, pw + (pc[phaseIdx] - pc[waterPhaseIdx]));
// compute the phase compositions
using MMPC = Opm::MiscibleMultiPhaseComposition<Scalar, FluidSystem>;
typename FluidSystem::template ParameterCache<Scalar> paramCache;
MMPC::solve(fs, paramCache, /*setViscosity=*/true, /*setEnthalpy=*/true);
}
else {
fs.setSaturation(waterPhaseIdx, 0.12);
fs.setSaturation(gasPhaseIdx, 1 - fs.saturation(waterPhaseIdx));
fs.setSaturation(naplPhaseIdx, 0);
// set the capillary pressures
const auto& matParams = materialLawParams(context, spaceIdx, timeIdx);
Scalar pc[numPhases];
MaterialLaw::capillaryPressures(pc, matParams, fs);
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
fs.setPressure(phaseIdx, pw + (pc[phaseIdx] - pc[waterPhaseIdx]));
// compute the phase compositions
using MMPC = Opm::MiscibleMultiPhaseComposition<Scalar, FluidSystem>;
typename FluidSystem::template ParameterCache<Scalar> paramCache;
MMPC::solve(fs, paramCache, /*setViscosity=*/true, /*setEnthalpy=*/true);
// set the contaminant mole fractions to zero. this is a little bit hacky...
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
fs.setMoleFraction(phaseIdx, NAPLIdx, 0.0);
if (phaseIdx == naplPhaseIdx)
continue;
Scalar sumx = 0;
for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx)
sumx += fs.moleFraction(phaseIdx, compIdx);
for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx)
fs.setMoleFraction(phaseIdx, compIdx,
fs.moleFraction(phaseIdx, compIdx) / sumx);
}
}
}
void computeThermalCondParams_(ThermalConductionLawParams& params, Scalar poro)
{
Scalar lambdaGranite = 2.8; // [W / (K m)]
// create a Fluid state which has all phases present
Opm::ImmiscibleFluidState<Scalar, FluidSystem> fs;
fs.setTemperature(293.15);
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
fs.setPressure(phaseIdx, 1.0135e5);
}
typename FluidSystem::template ParameterCache<Scalar> paramCache;
paramCache.updateAll(fs);
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
Scalar rho = FluidSystem::density(fs, paramCache, phaseIdx);
fs.setDensity(phaseIdx, rho);
}
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
Scalar lambdaSaturated;
if (FluidSystem::isLiquid(phaseIdx)) {
Scalar lambdaFluid = FluidSystem::thermalConductivity(fs, paramCache, phaseIdx);
lambdaSaturated =
std::pow(lambdaGranite, (1 - poro))
+
std::pow(lambdaFluid, poro);
}
else
lambdaSaturated = std::pow(lambdaGranite, (1 - poro));
params.setFullySaturatedLambda(phaseIdx, lambdaSaturated);
if (!FluidSystem::isLiquid(phaseIdx))
params.setVacuumLambda(lambdaSaturated);
}
}
void initInjectFluidState_()
{
injectFluidState_.setTemperature(383.0); // [K]
injectFluidState_.setPressure(gasPhaseIdx, 1e5); // [Pa]
injectFluidState_.setSaturation(gasPhaseIdx, 1.0); // [-]
Scalar xgH2O = 0.417;
injectFluidState_.setMoleFraction(gasPhaseIdx, H2OIdx, xgH2O); // [-]
injectFluidState_.setMoleFraction(gasPhaseIdx, airIdx, 1 - xgH2O); // [-]
injectFluidState_.setMoleFraction(gasPhaseIdx, NAPLIdx, 0.0); // [-]
// set the specific enthalpy of the gas phase
typename FluidSystem::template ParameterCache<Scalar> paramCache;
paramCache.updatePhase(injectFluidState_, gasPhaseIdx);
Scalar h = FluidSystem::enthalpy(injectFluidState_, paramCache, gasPhaseIdx);
injectFluidState_.setEnthalpy(gasPhaseIdx, h);
}
DimMatrix fineK_;
DimMatrix coarseK_;
Scalar finePorosity_;
Scalar coarsePorosity_;
MaterialLawParams fineMaterialParams_;
MaterialLawParams coarseMaterialParams_;
ThermalConductionLawParams thermalCondParams_;
SolidEnergyLawParams solidEnergyLawParams_;
Opm::CompositionalFluidState<Scalar, FluidSystem> injectFluidState_;
const Scalar eps_;
};
} // namespace Opm
#endif

View File

@ -0,0 +1,385 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \copydoc Opm::DiffusionProblem
*/
#ifndef EWOMS_POWER_INJECTION_PROBLEM_HH
#define EWOMS_POWER_INJECTION_PROBLEM_HH
#include <opm/models/ncp/ncpproperties.hh>
#include <opm/models/io/cubegridvanguard.hh>
#include <opm/material/fluidmatrixinteractions/LinearMaterial.hpp>
#include <opm/material/fluidmatrixinteractions/MaterialTraits.hpp>
#include <opm/material/fluidsystems/H2ON2FluidSystem.hpp>
#include <opm/material/fluidstates/CompositionalFluidState.hpp>
#include <opm/material/constraintsolvers/ComputeFromReferencePhase.hpp>
#include <dune/grid/yaspgrid.hh>
#include <dune/common/version.hh>
#include <dune/common/fvector.hh>
#include <dune/common/fmatrix.hh>
#include <sstream>
#include <string>
namespace Opm {
template <class TypeTag>
class DiffusionProblem;
}
namespace Opm::Properties {
namespace TTag {
struct DiffusionBaseProblem {};
} // namespace TTag
// Set the grid implementation to be used
template<class TypeTag>
struct Grid<TypeTag, TTag::DiffusionBaseProblem> { using type = Dune::YaspGrid</*dim=*/1>; };
// set the Vanguard property
template<class TypeTag>
struct Vanguard<TypeTag, TTag::DiffusionBaseProblem> { using type = Opm::CubeGridVanguard<TypeTag>; };
// Set the problem property
template<class TypeTag>
struct Problem<TypeTag, TTag::DiffusionBaseProblem> { using type = Opm::DiffusionProblem<TypeTag>; };
// Set the fluid system
template<class TypeTag>
struct FluidSystem<TypeTag, TTag::DiffusionBaseProblem>
{
private:
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
public:
using type = Opm::H2ON2FluidSystem<Scalar>;
};
// Set the material Law
template<class TypeTag>
struct MaterialLaw<TypeTag, TTag::DiffusionBaseProblem>
{
private:
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
static_assert(FluidSystem::numPhases == 2,
"A fluid system with two phases is required "
"for this problem!");
using Traits = Opm::TwoPhaseMaterialTraits<Scalar,
/*wettingPhaseIdx=*/FluidSystem::liquidPhaseIdx,
/*nonWettingPhaseIdx=*/FluidSystem::gasPhaseIdx>;
public:
using type = Opm::LinearMaterial<Traits>;
};
// Enable molecular diffusion for this problem
template<class TypeTag>
struct EnableDiffusion<TypeTag, TTag::DiffusionBaseProblem> { static constexpr bool value = true; };
} // namespace Opm::Properties
namespace Opm {
/*!
* \ingroup TestProblems
* \brief 1D problem which is driven by molecular diffusion.
*
* The domain is one meter long and completely filled with gas and
* closed on all boundaries. Its left half exhibits a slightly higher
* water concentration than the right one. After a while, the
* concentration of water will be equilibrate due to molecular
* diffusion.
*/
template <class TypeTag>
class DiffusionProblem : public GetPropType<TypeTag, Properties::BaseProblem>
{
using ParentType = GetPropType<TypeTag, Properties::BaseProblem>;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using GridView = GetPropType<TypeTag, Properties::GridView>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
using Model = GetPropType<TypeTag, Properties::Model>;
enum {
// number of phases
numPhases = FluidSystem::numPhases,
// phase indices
liquidPhaseIdx = FluidSystem::liquidPhaseIdx,
gasPhaseIdx = FluidSystem::gasPhaseIdx,
// component indices
H2OIdx = FluidSystem::H2OIdx,
N2Idx = FluidSystem::N2Idx,
// Grid and world dimension
dim = GridView::dimension,
dimWorld = GridView::dimensionworld
};
using EqVector = GetPropType<TypeTag, Properties::EqVector>;
using RateVector = GetPropType<TypeTag, Properties::RateVector>;
using BoundaryRateVector = GetPropType<TypeTag, Properties::BoundaryRateVector>;
using MaterialLaw = GetPropType<TypeTag, Properties::MaterialLaw>;
using MaterialLawParams = GetPropType<TypeTag, Properties::MaterialLawParams>;
using CoordScalar = typename GridView::ctype;
using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
public:
/*!
* \copydoc Doxygen::defaultProblemConstructor
*/
DiffusionProblem(Simulator& simulator)
: ParentType(simulator)
{ }
/*!
* \copydoc FvBaseProblem::finishInit
*/
void finishInit()
{
ParentType::finishInit();
FluidSystem::init();
temperature_ = 273.15 + 20.0;
materialParams_.finalize();
K_ = this->toDimMatrix_(1e-12); // [m^2]
setupInitialFluidStates_();
}
/*!
* \copydoc FvBaseMultiPhaseProblem::registerParameters
*/
static void registerParameters()
{
ParentType::registerParameters();
Parameters::SetDefault<Parameters::CellsX>(250);
if constexpr (dim > 1) {
Parameters::SetDefault<Parameters::CellsY>(1);
}
if constexpr (dim == 3) {
Parameters::SetDefault<Parameters::CellsZ>(1);
}
Parameters::SetDefault<Parameters::EndTime<Scalar>>(1e6);
Parameters::SetDefault<Parameters::InitialTimeStepSize<Scalar>>(1000);
}
/*!
* \name Auxiliary methods
*/
//! \{
/*!
* \copydoc FvBaseProblem::name
*/
std::string name() const
{ return std::string("diffusion_") + Model::name(); }
/*!
* \copydoc FvBaseProblem::endTimeStep
*/
void endTimeStep()
{
#ifndef NDEBUG
this->model().checkConservativeness();
// Calculate storage terms
EqVector storage;
this->model().globalStorage(storage);
// Write mass balance information for rank 0
if (this->gridView().comm().rank() == 0) {
std::cout << "Storage: " << storage << std::endl << std::flush;
}
#endif // NDEBUG
}
//! \}
/*!
* \name Soil parameters
*/
//! \{
/*!
* \copydoc FvBaseMultiPhaseProblem::intrinsicPermeability
*/
template <class Context>
const DimMatrix& intrinsicPermeability(const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ return K_; }
/*!
* \copydoc FvBaseMultiPhaseProblem::porosity
*/
template <class Context>
Scalar porosity(const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ return 0.35; }
/*!
* \copydoc FvBaseMultiPhaseProblem::materialLawParams
*/
template <class Context>
const MaterialLawParams&
materialLawParams(const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ return materialParams_; }
/*!
* \copydoc FvBaseMultiPhaseProblem::temperature
*/
template <class Context>
Scalar temperature(const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ return temperature_; }
//! \}
/*!
* \name Boundary conditions
*/
//! \{
/*!
* \copydoc FvBaseProblem::boundary
*
* This problem sets no-flow boundaries everywhere.
*/
template <class Context>
void boundary(BoundaryRateVector& values,
const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ values.setNoFlow(); }
//! \}
/*!
* \name Volumetric terms
*/
//! \{
/*!
* \copydoc FvBaseProblem::initial
*/
template <class Context>
void initial(PrimaryVariables& values,
const Context& context,
unsigned spaceIdx,
unsigned timeIdx) const
{
const auto& pos = context.pos(spaceIdx, timeIdx);
if (onLeftSide_(pos))
values.assignNaive(leftInitialFluidState_);
else
values.assignNaive(rightInitialFluidState_);
}
/*!
* \copydoc FvBaseProblem::source
*
* For this problem, the source term of all components is 0
* everywhere.
*/
template <class Context>
void source(RateVector& rate,
const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ rate = Scalar(0.0); }
//! \}
private:
bool onLeftSide_(const GlobalPosition& pos) const
{ return pos[0] < (this->boundingBoxMin()[0] + this->boundingBoxMax()[0]) / 2; }
void setupInitialFluidStates_()
{
// create the initial fluid state for the left half of the domain
leftInitialFluidState_.setTemperature(temperature_);
Scalar Sl = 0.0;
leftInitialFluidState_.setSaturation(liquidPhaseIdx, Sl);
leftInitialFluidState_.setSaturation(gasPhaseIdx, 1 - Sl);
Scalar p = 1e5;
leftInitialFluidState_.setPressure(liquidPhaseIdx, p);
leftInitialFluidState_.setPressure(gasPhaseIdx, p);
Scalar xH2O = 0.01;
leftInitialFluidState_.setMoleFraction(gasPhaseIdx, H2OIdx, xH2O);
leftInitialFluidState_.setMoleFraction(gasPhaseIdx, N2Idx, 1 - xH2O);
using CFRP = Opm::ComputeFromReferencePhase<Scalar, FluidSystem>;
typename FluidSystem::template ParameterCache<Scalar> paramCache;
CFRP::solve(leftInitialFluidState_, paramCache, gasPhaseIdx,
/*setViscosity=*/false, /*setEnthalpy=*/false);
// create the initial fluid state for the right half of the domain
rightInitialFluidState_.assign(leftInitialFluidState_);
xH2O = 0.0;
rightInitialFluidState_.setMoleFraction(gasPhaseIdx, H2OIdx, xH2O);
rightInitialFluidState_.setMoleFraction(gasPhaseIdx, N2Idx, 1 - xH2O);
CFRP::solve(rightInitialFluidState_, paramCache, gasPhaseIdx,
/*setViscosity=*/false, /*setEnthalpy=*/false);
}
DimMatrix K_;
MaterialLawParams materialParams_;
Opm::CompositionalFluidState<Scalar, FluidSystem> leftInitialFluidState_;
Opm::CompositionalFluidState<Scalar, FluidSystem> rightInitialFluidState_;
Scalar temperature_;
};
} // namespace Opm
#endif

View File

@ -0,0 +1,562 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \copydoc Opm::FingerProblem
*/
#ifndef EWOMS_FINGER_PROBLEM_HH
#define EWOMS_FINGER_PROBLEM_HH
#if HAVE_DUNE_ALUGRID
#include <dune/alugrid/grid.hh>
#endif
#include <dune/common/fmatrix.hh>
#include <dune/common/fvector.hh>
#include <dune/common/version.hh>
#include <dune/grid/utility/persistentcontainer.hh>
#include <opm/material/components/Air.hpp>
#include <opm/material/components/SimpleH2O.hpp>
#include <opm/material/fluidmatrixinteractions/EffToAbsLaw.hpp>
#include <opm/material/fluidmatrixinteractions/LinearMaterial.hpp>
#include <opm/material/fluidmatrixinteractions/MaterialTraits.hpp>
#include <opm/material/fluidmatrixinteractions/ParkerLenhard.hpp>
#include <opm/material/fluidmatrixinteractions/RegularizedVanGenuchten.hpp>
#include <opm/material/fluidstates/ImmiscibleFluidState.hpp>
#include <opm/material/fluidsystems/TwoPhaseImmiscibleFluidSystem.hpp>
#include <opm/models/common/multiphasebaseparameters.hh>
#include <opm/models/discretization/common/fvbasefdlocallinearizer.hh>
#include <opm/models/discretization/common/restrictprolong.hh>
#include <opm/models/immiscible/immiscibleproperties.hh>
#include <opm/models/io/structuredgridvanguard.hh>
#include <string>
namespace Opm {
template <class TypeTag>
class FingerProblem;
} // namespace Opm
namespace Opm::Properties {
// Create new type tags
namespace TTag {
struct FingerBaseProblem { using InheritsFrom = std::tuple<StructuredGridVanguard>; };
} // end namespace TTag
#if HAVE_DUNE_ALUGRID
// use dune-alugrid if available
template<class TypeTag>
struct Grid<TypeTag, TTag::FingerBaseProblem>
{ using type = Dune::ALUGrid</*dim=*/2,
/*dimWorld=*/2,
Dune::cube,
Dune::nonconforming>; };
#endif
// Set the problem property
template<class TypeTag>
struct Problem<TypeTag, TTag::FingerBaseProblem> { using type = Opm::FingerProblem<TypeTag>; };
// Set the wetting phase
template<class TypeTag>
struct WettingPhase<TypeTag, TTag::FingerBaseProblem>
{
private:
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
public:
using type = Opm::LiquidPhase<Scalar, Opm::SimpleH2O<Scalar> >;
};
// Set the non-wetting phase
template<class TypeTag>
struct NonwettingPhase<TypeTag, TTag::FingerBaseProblem>
{
private:
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
public:
using type = Opm::GasPhase<Scalar, Opm::Air<Scalar> >;
};
// Set the material Law
template<class TypeTag>
struct MaterialLaw<TypeTag, TTag::FingerBaseProblem>
{
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
using Traits = Opm::TwoPhaseMaterialTraits<Scalar,
/*wettingPhaseIdx=*/FluidSystem::wettingPhaseIdx,
/*nonWettingPhaseIdx=*/FluidSystem::nonWettingPhaseIdx>;
// use the parker-lenhard hysteresis law
using ParkerLenhard = Opm::ParkerLenhard<Traits>;
using type = ParkerLenhard;
};
// Enable constraints
template<class TypeTag>
struct EnableConstraints<TypeTag, TTag::FingerBaseProblem> { static constexpr int value = true; };
} // namespace Opm::Properties
namespace Opm::Parameters {
template<class Scalar>
struct InitialWaterSaturation { static constexpr Scalar value = 0.01; };
} // namespace Opm::Parameters
namespace Opm {
/*!
* \ingroup TestProblems
*
* \brief Two-phase problem featuring some gravity-driven saturation
* fingers.
*
* The domain of this problem is sized 10cm times 1m and is initially
* dry. Water is then injected at three locations on the top of the
* domain which leads to gravity fingering. The boundary conditions
* used are no-flow for the left and right and top of the domain and
* free-flow at the bottom. This problem uses the Parker-Lenhard
* hystersis model which might lead to non-monotonic saturation in the
* fingers if the right material parameters is chosen and the spatial
* discretization is fine enough.
*/
template <class TypeTag>
class FingerProblem : public GetPropType<TypeTag, Properties::BaseProblem>
{
//!\cond SKIP_THIS
using ParentType = GetPropType<TypeTag, Properties::BaseProblem>;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using GridView = GetPropType<TypeTag, Properties::GridView>;
using Indices = GetPropType<TypeTag, Properties::Indices>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
using WettingPhase = GetPropType<TypeTag, Properties::WettingPhase>;
using NonwettingPhase = GetPropType<TypeTag, Properties::NonwettingPhase>;
using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
using Constraints = GetPropType<TypeTag, Properties::Constraints>;
using Model = GetPropType<TypeTag, Properties::Model>;
enum {
// number of phases
numPhases = FluidSystem::numPhases,
// phase indices
wettingPhaseIdx = FluidSystem::wettingPhaseIdx,
nonWettingPhaseIdx = FluidSystem::nonWettingPhaseIdx,
// equation indices
contiWettingEqIdx = Indices::conti0EqIdx + wettingPhaseIdx,
// Grid and world dimension
dim = GridView::dimension,
dimWorld = GridView::dimensionworld
};
using ElementContext = GetPropType<TypeTag, Properties::ElementContext>;
using Stencil = GetPropType<TypeTag, Properties::Stencil> ;
enum { codim = Stencil::Entity::codimension };
using EqVector = GetPropType<TypeTag, Properties::EqVector>;
using RateVector = GetPropType<TypeTag, Properties::RateVector>;
using BoundaryRateVector = GetPropType<TypeTag, Properties::BoundaryRateVector>;
using ParkerLenhard = typename GetProp<TypeTag, Properties::MaterialLaw>::ParkerLenhard;
using MaterialLaw = GetPropType<TypeTag, Properties::MaterialLaw>;
using MaterialLawParams = GetPropType<TypeTag, Properties::MaterialLawParams>;
using CoordScalar = typename GridView::ctype;
using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
using Grid = typename GridView :: Grid;
using MaterialLawParamsContainer = Dune::PersistentContainer< Grid, std::shared_ptr< MaterialLawParams > > ;
//!\endcond
public:
using RestrictProlongOperator = CopyRestrictProlong< Grid, MaterialLawParamsContainer >;
/*!
* \copydoc Doxygen::defaultProblemConstructor
*/
FingerProblem(Simulator& simulator)
: ParentType(simulator),
materialParams_( simulator.vanguard().grid(), codim )
{
}
/*!
* \name Auxiliary methods
*/
//! \{
/*!
* \brief \copydoc FvBaseProblem::restrictProlongOperator
*/
RestrictProlongOperator restrictProlongOperator()
{
return RestrictProlongOperator( materialParams_ );
}
/*!
* \copydoc FvBaseProblem::name
*/
std::string name() const
{ return
std::string("finger") +
"_" + Model::name() +
"_" + Model::discretizationName() +
(this->model().enableGridAdaptation()?"_adaptive":"");
}
/*!
* \copydoc FvBaseMultiPhaseProblem::registerParameters
*/
static void registerParameters()
{
ParentType::registerParameters();
Parameters::Register<Parameters::InitialWaterSaturation<Scalar>>
("The initial saturation in the domain [] of the wetting phase");
Parameters::SetDefault<Parameters::CellsX>(20);
Parameters::SetDefault<Parameters::DomainSizeX<Scalar>>(0.1);
if constexpr (dim > 1) {
Parameters::SetDefault<Parameters::CellsY>(70);
Parameters::SetDefault<Parameters::DomainSizeY<Scalar>>(0.3);
}
if constexpr (dim == 3) {
Parameters::SetDefault<Parameters::CellsZ>(1);
Parameters::SetDefault<Parameters::DomainSizeZ<Scalar>>(0.1);
}
// Use forward differences
Parameters::SetDefault<Parameters::NumericDifferenceMethod>(+1);
Parameters::SetDefault<Parameters::EndTime<Scalar>>(215);
Parameters::SetDefault<Parameters::InitialTimeStepSize<Scalar>>(10);
Parameters::SetDefault<Parameters::EnableGravity>(true);
}
/*!
* \copydoc FvBaseProblem::finishInit()
*/
void finishInit()
{
ParentType::finishInit();
eps_ = 3e-6;
temperature_ = 273.15 + 20; // -> 20°C
FluidSystem::init();
// parameters for the Van Genuchten law of the main imbibition
// and the main drainage curves.
micParams_.setVgAlpha(0.0037);
micParams_.setVgN(4.7);
micParams_.finalize();
mdcParams_.setVgAlpha(0.0037);
mdcParams_.setVgN(4.7);
mdcParams_.finalize();
// initialize the material parameter objects of the individual
// finite volumes, resize will resize the container to the number of elements
materialParams_.resize();
for (auto it = materialParams_.begin(),
end = materialParams_.end(); it != end; ++it ) {
std::shared_ptr< MaterialLawParams >& materialParams = *it ;
if( ! materialParams )
{
materialParams.reset( new MaterialLawParams() );
materialParams->setMicParams(&micParams_);
materialParams->setMdcParams(&mdcParams_);
materialParams->setSwr(0.0);
materialParams->setSnr(0.1);
materialParams->finalize();
ParkerLenhard::reset(*materialParams);
}
}
K_ = this->toDimMatrix_(4.6e-10);
setupInitialFluidState_();
}
/*!
* \copydoc FvBaseProblem::endTimeStep
*/
void endTimeStep()
{
#ifndef NDEBUG
// checkConservativeness() does not include the effect of constraints, so we
// disable it for this problem...
//this->model().checkConservativeness();
// Calculate storage terms
EqVector storage;
this->model().globalStorage(storage);
// Write mass balance information for rank 0
if (this->gridView().comm().rank() == 0) {
std::cout << "Storage: " << storage << std::endl << std::flush;
}
#endif // NDEBUG
// update the history of the hysteresis law
ElementContext elemCtx(this->simulator());
for (const auto& elem : elements(this->gridView())) {
elemCtx.updateAll(elem);
size_t numDofs = elemCtx.numDof(/*timeIdx=*/0);
for (unsigned scvIdx = 0; scvIdx < numDofs; ++scvIdx)
{
MaterialLawParams& materialParam = materialLawParams( elemCtx, scvIdx, /*timeIdx=*/0 );
const auto& fs = elemCtx.intensiveQuantities(scvIdx, /*timeIdx=*/0).fluidState();
ParkerLenhard::update(materialParam, fs);
}
}
}
//! \}
/*!
* \name Soil parameters
*/
//! \{
/*!
* \copydoc FvBaseMultiPhaseProblem::temperature
*/
template <class Context>
Scalar temperature(const Context& /*context*/, unsigned /*spaceIdx*/, unsigned /*timeIdx*/) const
{ return temperature_; }
/*!
* \copydoc FvBaseMultiPhaseProblem::intrinsicPermeability
*/
template <class Context>
const DimMatrix& intrinsicPermeability(const Context& /*context*/, unsigned /*spaceIdx*/, unsigned /*timeIdx*/) const
{ return K_; }
/*!
* \copydoc FvBaseMultiPhaseProblem::porosity
*/
template <class Context>
Scalar porosity(const Context& /*context*/, unsigned /*spaceIdx*/, unsigned /*timeIdx*/) const
{ return 0.4; }
/*!
* \copydoc FvBaseMultiPhaseProblem::materialLawParams
*/
template <class Context>
MaterialLawParams& materialLawParams(const Context& context,
unsigned spaceIdx, unsigned timeIdx)
{
const auto& entity = context.stencil(timeIdx).entity(spaceIdx);
assert(materialParams_[entity]);
return *materialParams_[entity];
}
/*!
* \copydoc FvBaseMultiPhaseProblem::materialLawParams
*/
template <class Context>
const MaterialLawParams& materialLawParams(const Context& context,
unsigned spaceIdx, unsigned timeIdx) const
{
const auto& entity = context.stencil(timeIdx).entity( spaceIdx );
assert(materialParams_[entity]);
return *materialParams_[entity];
}
//! \}
/*!
* \name Boundary conditions
*/
//! \{
/*!
* \copydoc FvBaseProblem::boundary
*/
template <class Context>
void boundary(BoundaryRateVector& values, const Context& context,
unsigned spaceIdx, unsigned timeIdx) const
{
const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
if (onLeftBoundary_(pos) || onRightBoundary_(pos) || onLowerBoundary_(pos))
values.setNoFlow();
else {
assert(onUpperBoundary_(pos));
values.setFreeFlow(context, spaceIdx, timeIdx, initialFluidState_);
}
// override the value for the liquid phase by forced
// imbibition of water on inlet boundary segments
if (onInlet_(pos)) {
values[contiWettingEqIdx] = -0.001; // [kg/(m^2 s)]
}
}
//! \}
/*!
* \name Volumetric terms
*/
//! \{
/*!
* \copydoc FvBaseProblem::initial
*/
template <class Context>
void initial(PrimaryVariables& values, const Context& /*context*/, unsigned /*spaceIdx*/, unsigned /*timeIdx*/) const
{
// assign the primary variables
values.assignNaive(initialFluidState_);
}
/*!
* \copydoc FvBaseProblem::constraints
*/
template <class Context>
void constraints(Constraints& constraints, const Context& context,
unsigned spaceIdx, unsigned timeIdx) const
{
const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
if (onUpperBoundary_(pos) && !onInlet_(pos)) {
constraints.setActive(true);
constraints.assignNaive(initialFluidState_);
}
else if (onLowerBoundary_(pos)) {
constraints.setActive(true);
constraints.assignNaive(initialFluidState_);
}
}
/*!
* \copydoc FvBaseProblem::source
*
* For this problem, the source term of all components is 0
* everywhere.
*/
template <class Context>
void source(RateVector& rate, const Context& /*context*/,
unsigned /*spaceIdx*/, unsigned /*timeIdx*/) const
{ rate = Scalar(0.0); }
//! \}
private:
bool onLeftBoundary_(const GlobalPosition& pos) const
{ return pos[0] < this->boundingBoxMin()[0] + eps_; }
bool onRightBoundary_(const GlobalPosition& pos) const
{ return pos[0] > this->boundingBoxMax()[0] - eps_; }
bool onLowerBoundary_(const GlobalPosition& pos) const
{ return pos[1] < this->boundingBoxMin()[1] + eps_; }
bool onUpperBoundary_(const GlobalPosition& pos) const
{ return pos[1] > this->boundingBoxMax()[1] - eps_; }
bool onInlet_(const GlobalPosition& pos) const
{
Scalar width = this->boundingBoxMax()[0] - this->boundingBoxMin()[0];
Scalar lambda = (this->boundingBoxMax()[0] - pos[0]) / width;
if (!onUpperBoundary_(pos))
return false;
Scalar xInject[] = { 0.25, 0.75 };
Scalar injectLen[] = { 0.1, 0.1 };
for (unsigned i = 0; i < sizeof(xInject) / sizeof(Scalar); ++i) {
if (xInject[i] - injectLen[i] / 2 < lambda
&& lambda < xInject[i] + injectLen[i] / 2)
return true;
}
return false;
}
void setupInitialFluidState_()
{
auto& fs = initialFluidState_;
fs.setPressure(wettingPhaseIdx, /*pressure=*/1e5);
Scalar Sw = Parameters::Get<Parameters::InitialWaterSaturation<Scalar>>();
fs.setSaturation(wettingPhaseIdx, Sw);
fs.setSaturation(nonWettingPhaseIdx, 1 - Sw);
fs.setTemperature(temperature_);
// set the absolute pressures
Scalar pn = 1e5;
fs.setPressure(nonWettingPhaseIdx, pn);
fs.setPressure(wettingPhaseIdx, pn);
typename FluidSystem::template ParameterCache<Scalar> paramCache;
paramCache.updateAll(fs);
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
fs.setDensity(phaseIdx, FluidSystem::density(fs, paramCache, phaseIdx));
fs.setViscosity(phaseIdx, FluidSystem::viscosity(fs, paramCache, phaseIdx));
}
}
DimMatrix K_;
typename MaterialLawParams::VanGenuchtenParams micParams_;
typename MaterialLawParams::VanGenuchtenParams mdcParams_;
MaterialLawParamsContainer materialParams_;
Opm::ImmiscibleFluidState<Scalar, FluidSystem> initialFluidState_;
Scalar temperature_;
Scalar eps_;
};
} // namespace Opm
#endif

View File

@ -0,0 +1,663 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \copydoc Opm::FractureProblem
*/
#ifndef EWOMS_FRACTURE_PROBLEM_HH
#define EWOMS_FRACTURE_PROBLEM_HH
#if HAVE_DUNE_ALUGRID
// avoid reordering of macro elements, otherwise this problem won't work
#define DISABLE_ALUGRID_SFC_ORDERING 1
#include <dune/alugrid/grid.hh>
#include <dune/alugrid/dgf.hh>
#else
#error "dune-alugrid not found!"
#endif
#include <opm/models/discretefracture/discretefracturemodel.hh>
#include <opm/models/io/dgfvanguard.hh>
#include <opm/material/fluidmatrixinteractions/RegularizedBrooksCorey.hpp>
#include <opm/material/fluidmatrixinteractions/RegularizedVanGenuchten.hpp>
#include <opm/material/fluidmatrixinteractions/LinearMaterial.hpp>
#include <opm/material/fluidmatrixinteractions/EffToAbsLaw.hpp>
#include <opm/material/fluidmatrixinteractions/MaterialTraits.hpp>
#include <opm/material/thermal/SomertonThermalConductionLaw.hpp>
#include <opm/material/thermal/ConstantSolidHeatCapLaw.hpp>
#include <opm/material/fluidsystems/TwoPhaseImmiscibleFluidSystem.hpp>
#include <opm/material/components/SimpleH2O.hpp>
#include <opm/material/components/Dnapl.hpp>
#include <dune/common/version.hh>
#include <dune/common/fmatrix.hh>
#include <dune/common/fvector.hh>
#include <iostream>
#include <sstream>
#include <string>
namespace Opm {
template <class TypeTag>
class FractureProblem;
}
namespace Opm::Properties {
// Create a type tag for the problem
// Create new type tags
namespace TTag {
struct FractureProblem { using InheritsFrom = std::tuple<DiscreteFractureModel>; };
} // end namespace TTag
// Set the grid type
template<class TypeTag>
struct Grid<TypeTag, TTag::FractureProblem>
{ using type = Dune::ALUGrid</*dim=*/2, /*dimWorld=*/2, Dune::simplex, Dune::nonconforming>; };
// Set the Vanguard property
template<class TypeTag>
struct Vanguard<TypeTag, TTag::FractureProblem> { using type = Opm::DgfVanguard<TypeTag>; };
// Set the problem property
template<class TypeTag>
struct Problem<TypeTag, TTag::FractureProblem> { using type = Opm::FractureProblem<TypeTag>; };
// Set the wetting phase
template<class TypeTag>
struct WettingPhase<TypeTag, TTag::FractureProblem>
{
private:
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
public:
using type = Opm::LiquidPhase<Scalar, Opm::SimpleH2O<Scalar> >;
};
// Set the non-wetting phase
template<class TypeTag>
struct NonwettingPhase<TypeTag, TTag::FractureProblem>
{
private:
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
public:
using type = Opm::LiquidPhase<Scalar, Opm::DNAPL<Scalar> >;
};
// Set the material Law
template<class TypeTag>
struct MaterialLaw<TypeTag, TTag::FractureProblem>
{
private:
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
enum { wettingPhaseIdx = FluidSystem::wettingPhaseIdx };
enum { nonWettingPhaseIdx = FluidSystem::nonWettingPhaseIdx };
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using Traits = Opm::TwoPhaseMaterialTraits<Scalar,
/*wettingPhaseIdx=*/FluidSystem::wettingPhaseIdx,
/*nonWettingPhaseIdx=*/FluidSystem::nonWettingPhaseIdx>;
// define the material law which is parameterized by effective
// saturations
using EffectiveLaw = Opm::RegularizedBrooksCorey<Traits>;
// using EffectiveLaw = RegularizedVanGenuchten<Traits>;
// using EffectiveLaw = LinearMaterial<Traits>;
public:
using type = Opm::EffToAbsLaw<EffectiveLaw>;
};
// Enable the energy equation
template<class TypeTag>
struct EnableEnergy<TypeTag, TTag::FractureProblem> { static constexpr bool value = true; };
// Set the thermal conduction law
template<class TypeTag>
struct ThermalConductionLaw<TypeTag, TTag::FractureProblem>
{
private:
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
public:
// define the material law parameterized by absolute saturations
using type = Opm::SomertonThermalConductionLaw<FluidSystem, Scalar>;
};
// set the energy storage law for the solid phase
template<class TypeTag>
struct SolidEnergyLaw<TypeTag, TTag::FractureProblem>
{ using type = Opm::ConstantSolidHeatCapLaw<GetPropType<TypeTag, Properties::Scalar>>; };
// For this problem, we use constraints to specify the left boundary
template<class TypeTag>
struct EnableConstraints<TypeTag, TTag::FractureProblem> { static constexpr bool value = true; };
} // namespace Opm::Properties
namespace Opm {
/*!
* \ingroup TestProblems
*
* \brief Two-phase problem which involves fractures
*
* The domain is initially completely saturated by the oil phase,
* except for the left side, which is fully water saturated. Since the
* capillary pressure in the fractures is lower than in the rock
* matrix and the material is hydrophilic, water infiltrates through
* the fractures and gradually pushes the oil out on the right side,
* where the pressure is kept constant.
*/
template <class TypeTag>
class FractureProblem : public GetPropType<TypeTag, Properties::BaseProblem>
{
using ParentType = GetPropType<TypeTag, Properties::BaseProblem>;
using GridView = GetPropType<TypeTag, Properties::GridView>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
using WettingPhase = GetPropType<TypeTag, Properties::WettingPhase>;
using NonwettingPhase = GetPropType<TypeTag, Properties::NonwettingPhase>;
using Constraints = GetPropType<TypeTag, Properties::Constraints>;
using EqVector = GetPropType<TypeTag, Properties::EqVector>;
using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
using BoundaryRateVector = GetPropType<TypeTag, Properties::BoundaryRateVector>;
using RateVector = GetPropType<TypeTag, Properties::RateVector>;
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using MaterialLaw = GetPropType<TypeTag, Properties::MaterialLaw>;
using MaterialLawParams = GetPropType<TypeTag, Properties::MaterialLawParams>;
using ThermalConductionLawParams = GetPropType<TypeTag, Properties::ThermalConductionLawParams>;
using SolidEnergyLawParams = GetPropType<TypeTag, Properties::SolidEnergyLawParams>;
using Model = GetPropType<TypeTag, Properties::Model>;
enum {
// phase indices
wettingPhaseIdx = MaterialLaw::wettingPhaseIdx,
nonWettingPhaseIdx = MaterialLaw::nonWettingPhaseIdx,
// number of phases
numPhases = FluidSystem::numPhases,
// Grid and world dimension
dim = GridView::dimension,
dimWorld = GridView::dimensionworld
};
using FluidState = Opm::ImmiscibleFluidState<Scalar, FluidSystem>;
using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>;
using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
template <int dim>
struct FaceLayout
{
bool contains(Dune::GeometryType gt)
{ return gt.dim() == dim - 1; }
};
using FaceMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
using FractureMapper = Opm::FractureMapper<TypeTag>;
public:
/*!
* \copydoc Doxygen::defaultProblemConstructor
*/
FractureProblem(Simulator& simulator)
: ParentType(simulator)
{ }
/*!
* \copydoc FvBaseProblem::finishInit
*/
void finishInit()
{
ParentType::finishInit();
eps_ = 3e-6;
temperature_ = 273.15 + 20; // -> 20°C
matrixMaterialParams_.setResidualSaturation(wettingPhaseIdx, 0.0);
matrixMaterialParams_.setResidualSaturation(nonWettingPhaseIdx, 0.0);
fractureMaterialParams_.setResidualSaturation(wettingPhaseIdx, 0.0);
fractureMaterialParams_.setResidualSaturation(nonWettingPhaseIdx, 0.0);
#if 0 // linear
matrixMaterialParams_.setEntryPC(0.0);
matrixMaterialParams_.setMaxPC(2000.0);
fractureMaterialParams_.setEntryPC(0.0);
fractureMaterialParams_.setMaxPC(1000.0);
#endif
#if 1 // Brooks-Corey
matrixMaterialParams_.setEntryPressure(2000);
matrixMaterialParams_.setLambda(2.0);
matrixMaterialParams_.setPcLowSw(1e-1);
fractureMaterialParams_.setEntryPressure(1000);
fractureMaterialParams_.setLambda(2.0);
fractureMaterialParams_.setPcLowSw(5e-2);
#endif
#if 0 // van Genuchten
matrixMaterialParams_.setVgAlpha(0.0037);
matrixMaterialParams_.setVgN(4.7);
fractureMaterialParams_.setVgAlpha(0.0025);
fractureMaterialParams_.setVgN(4.7);
#endif
matrixMaterialParams_.finalize();
fractureMaterialParams_.finalize();
matrixK_ = this->toDimMatrix_(1e-15); // m^2
fractureK_ = this->toDimMatrix_(1e5 * 1e-15); // m^2
matrixPorosity_ = 0.10;
fracturePorosity_ = 0.25;
fractureWidth_ = 1e-3; // [m]
// initialize the energy-related parameters
initEnergyParams_(thermalConductionParams_, matrixPorosity_);
}
/*!
* \copydoc FvBaseMultiPhaseProblem::registerParameters
*/
static void registerParameters()
{
ParentType::registerParameters();
Parameters::SetDefault<Parameters::GridFile>("data/fracture.art.dgf");
Parameters::SetDefault<Parameters::EndTime<Scalar>>(3e3);
Parameters::SetDefault<Parameters::InitialTimeStepSize<Scalar>>(100);
}
/*!
* \name Auxiliary methods
*/
//! \{
/*!
* \copydoc FvBaseProblem::name
*/
std::string name() const
{
std::ostringstream oss;
oss << "fracture_" << Model::name();
return oss.str();
}
/*!
* \brief Called directly after the time integration.
*/
void endTimeStep()
{
#ifndef NDEBUG
// checkConservativeness() does not include the effect of constraints, so we
// disable it for this problem...
//this->model().checkConservativeness();
// Calculate storage terms
EqVector storage;
this->model().globalStorage(storage);
// Write mass balance information for rank 0
if (this->gridView().comm().rank() == 0) {
std::cout << "Storage: " << storage << std::endl << std::flush;
}
#endif // NDEBUG
}
/*!
* \copydoc FvBaseMultiPhaseProblem::temperature
*/
template <class Context>
Scalar temperature([[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{ return temperature_; }
// \}
/*!
* \name Soil parameters
*/
//! \{
/*!
* \copydoc FvBaseMultiPhaseProblem::intrinsicPermeability
*/
template <class Context>
const DimMatrix& intrinsicPermeability([[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{ return matrixK_; }
/*!
* \brief Intrinsic permeability of fractures.
*
* \copydoc Doxygen::contextParams
*/
template <class Context>
const DimMatrix& fractureIntrinsicPermeability([[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{ return fractureK_; }
/*!
* \copydoc FvBaseMultiPhaseProblem::porosity
*/
template <class Context>
Scalar porosity([[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{ return matrixPorosity_; }
/*!
* \brief The porosity inside the fractures.
*
* \copydoc Doxygen::contextParams
*/
template <class Context>
Scalar fracturePorosity([[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{ return fracturePorosity_; }
/*!
* \copydoc FvBaseMultiPhaseProblem::materialLawParams
*/
template <class Context>
const MaterialLawParams& materialLawParams([[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{ return matrixMaterialParams_; }
/*!
* \brief The parameters for the material law inside the fractures.
*
* \copydoc Doxygen::contextParams
*/
template <class Context>
const MaterialLawParams& fractureMaterialLawParams([[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{ return fractureMaterialParams_; }
/*!
* \brief Returns the object representating the fracture topology.
*/
const FractureMapper& fractureMapper() const
{ return this->simulator().vanguard().fractureMapper(); }
/*!
* \brief Returns the width of the fracture.
*
* \todo This method should get one face index instead of two
* vertex indices. This probably requires a new context
* class, though.
*
* \param context The execution context.
* \param spaceIdx1 The local index of the edge's first edge.
* \param spaceIdx2 The local index of the edge's second edge.
* \param timeIdx The index used by the time discretization.
*/
template <class Context>
Scalar fractureWidth([[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx1,
[[maybe_unused]] unsigned spaceIdx2,
[[maybe_unused]] unsigned timeIdx) const
{ return fractureWidth_; }
/*!
* \copydoc FvBaseMultiPhaseProblem::thermalConductionParams
*/
template <class Context>
const ThermalConductionLawParams&
thermalConductionLawParams([[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{ return thermalConductionParams_; }
/*!
* \brief Return the parameters for the energy storage law of the rock
*
* In this case, we assume the rock-matrix to be granite.
*/
template <class Context>
const SolidEnergyLawParams&
solidEnergyLawParams([[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{ return solidEnergyParams_; }
// \}
/*!
* \name Boundary conditions
*/
// \{
/*!
* \copydoc FvBaseProblem::boundary
*/
template <class Context>
void boundary(BoundaryRateVector& values, const Context& context,
unsigned spaceIdx, unsigned timeIdx) const
{
const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
if (onRightBoundary_(pos)) {
// on the right boundary, we impose a free-flow
// (i.e. Dirichlet) condition
FluidState fluidState;
fluidState.setTemperature(temperature_);
fluidState.setSaturation(wettingPhaseIdx, 0.0);
fluidState.setSaturation(nonWettingPhaseIdx,
1.0 - fluidState.saturation(wettingPhaseIdx));
fluidState.setPressure(wettingPhaseIdx, 1e5);
fluidState.setPressure(nonWettingPhaseIdx, fluidState.pressure(wettingPhaseIdx));
typename FluidSystem::template ParameterCache<Scalar> paramCache;
paramCache.updateAll(fluidState);
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
fluidState.setDensity(phaseIdx,
FluidSystem::density(fluidState, paramCache, phaseIdx));
fluidState.setViscosity(phaseIdx,
FluidSystem::viscosity(fluidState, paramCache, phaseIdx));
}
// set a free flow (i.e. Dirichlet) boundary
values.setFreeFlow(context, spaceIdx, timeIdx, fluidState);
}
else
// for the upper, lower and left boundaries, use a no-flow
// condition (i.e. a Neumann 0 condition)
values.setNoFlow();
}
// \}
/*!
* \name Volumetric terms
*/
// \{
/*!
* \copydoc FvBaseProblem::constraints
*/
template <class Context>
void constraints(Constraints& constraints, const Context& context,
unsigned spaceIdx, unsigned timeIdx) const
{
const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
if (!onLeftBoundary_(pos))
// only impose constraints adjacent to the left boundary
return;
unsigned globalIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
if (!fractureMapper().isFractureVertex(globalIdx)) {
// do not impose constraints if the finite volume does
// not contain fractures.
return;
}
// if the current finite volume is on the left boundary
// and features a fracture, specify the fracture fluid
// state.
FluidState fractureFluidState;
fractureFluidState.setTemperature(temperature_ + 10.0);
fractureFluidState.setSaturation(wettingPhaseIdx, 1.0);
fractureFluidState.setSaturation(nonWettingPhaseIdx,
1.0 - fractureFluidState.saturation(
wettingPhaseIdx));
Scalar pCFracture[numPhases];
MaterialLaw::capillaryPressures(pCFracture, fractureMaterialParams_,
fractureFluidState);
fractureFluidState.setPressure(wettingPhaseIdx, /*pressure=*/1.0e5);
fractureFluidState.setPressure(nonWettingPhaseIdx,
fractureFluidState.pressure(wettingPhaseIdx)
+ (pCFracture[nonWettingPhaseIdx]
- pCFracture[wettingPhaseIdx]));
constraints.setActive(true);
constraints.assignNaiveFromFracture(fractureFluidState,
matrixMaterialParams_);
}
/*!
* \copydoc FvBaseProblem::initial
*/
template <class Context>
void initial(PrimaryVariables& values,
[[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{
FluidState fluidState;
fluidState.setTemperature(temperature_);
fluidState.setPressure(FluidSystem::wettingPhaseIdx, /*pressure=*/1e5);
fluidState.setPressure(nonWettingPhaseIdx, fluidState.pressure(wettingPhaseIdx));
fluidState.setSaturation(wettingPhaseIdx, 0.0);
fluidState.setSaturation(nonWettingPhaseIdx,
1.0 - fluidState.saturation(wettingPhaseIdx));
values.assignNaive(fluidState);
}
/*!
* \copydoc FvBaseProblem::source
*
* For this problem, the source term of all components is 0
* everywhere.
*/
template <class Context>
void source(RateVector& rate,
[[maybe_unused]] const Context& context,
[[maybe_unused]] unsigned spaceIdx,
[[maybe_unused]] unsigned timeIdx) const
{ rate = Scalar(0.0); }
// \}
private:
bool onLeftBoundary_(const GlobalPosition& pos) const
{ return pos[0] < this->boundingBoxMin()[0] + eps_; }
bool onRightBoundary_(const GlobalPosition& pos) const
{ return pos[0] > this->boundingBoxMax()[0] - eps_; }
bool onLowerBoundary_(const GlobalPosition& pos) const
{ return pos[1] < this->boundingBoxMin()[1] + eps_; }
bool onUpperBoundary_(const GlobalPosition& pos) const
{ return pos[1] > this->boundingBoxMax()[1] - eps_; }
void initEnergyParams_(ThermalConductionLawParams& params, Scalar poro)
{
// assume the volumetric heat capacity of granite
solidEnergyParams_.setSolidHeatCapacity(790.0 // specific heat capacity of granite [J / (kg K)]
* 2700.0); // density of granite [kg/m^3]
solidEnergyParams_.finalize();
Scalar lambdaGranite = 2.8; // [W / (K m)]
// create a Fluid state which has all phases present
Opm::ImmiscibleFluidState<Scalar, FluidSystem> fs;
fs.setTemperature(293.15);
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
fs.setPressure(phaseIdx, 1.0135e5);
}
typename FluidSystem::template ParameterCache<Scalar> paramCache;
paramCache.updateAll(fs);
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
Scalar rho = FluidSystem::density(fs, paramCache, phaseIdx);
fs.setDensity(phaseIdx, rho);
}
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
Scalar lambdaSaturated;
if (FluidSystem::isLiquid(phaseIdx)) {
Scalar lambdaFluid = FluidSystem::thermalConductivity(fs, paramCache, phaseIdx);
lambdaSaturated =
std::pow(lambdaGranite, (1 - poro))
+ std::pow(lambdaFluid, poro);
}
else
lambdaSaturated = std::pow(lambdaGranite, (1 - poro));
params.setFullySaturatedLambda(phaseIdx, lambdaSaturated);
}
Scalar lambdaVac = std::pow(lambdaGranite, (1 - poro));
params.setVacuumLambda(lambdaVac);
}
DimMatrix matrixK_;
DimMatrix fractureK_;
Scalar matrixPorosity_;
Scalar fracturePorosity_;
Scalar fractureWidth_;
MaterialLawParams fractureMaterialParams_;
MaterialLawParams matrixMaterialParams_;
ThermalConductionLawParams thermalConductionParams_;
SolidEnergyLawParams solidEnergyParams_;
Scalar temperature_;
Scalar eps_;
};
} // namespace Opm
#endif // EWOMS_FRACTURE_PROBLEM_HH

View File

@ -0,0 +1,403 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \copydoc Opm::GroundWaterProblem
*/
#ifndef EWOMS_GROUND_WATER_PROBLEM_HH
#define EWOMS_GROUND_WATER_PROBLEM_HH
#include <dune/common/fmatrix.hh>
#include <dune/common/fvector.hh>
#include <dune/common/version.hh>
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/io/file/dgfparser/dgfyasp.hh>
#include <opm/material/components/SimpleH2O.hpp>
#include <opm/material/fluidstates/ImmiscibleFluidState.hpp>
#include <opm/material/fluidsystems/LiquidPhase.hpp>
#include <opm/models/common/multiphasebaseparameters.hh>
#include <opm/models/immiscible/immiscibleproperties.hh>
#include <opm/simulators/linalg/parallelistlbackend.hh>
#include <sstream>
#include <string>
namespace Opm {
template <class TypeTag>
class GroundWaterProblem;
}
namespace Opm::Properties {
namespace TTag {
struct GroundWaterBaseProblem {};
}
template<class TypeTag>
struct Fluid<TypeTag, TTag::GroundWaterBaseProblem>
{
private:
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
public:
using type = Opm::LiquidPhase<Scalar, Opm::SimpleH2O<Scalar> >;
};
// Set the grid type
template<class TypeTag>
struct Grid<TypeTag, TTag::GroundWaterBaseProblem> { using type = Dune::YaspGrid<2>; };
// struct Grid<TypeTag, TTag::GroundWaterBaseProblem> { using type = Dune::SGrid<2, 2>; };
template<class TypeTag>
struct Problem<TypeTag, TTag::GroundWaterBaseProblem>
{ using type = Opm::GroundWaterProblem<TypeTag>; };
// Use the conjugated gradient linear solver with the default preconditioner (i.e.,
// ILU-0) from dune-istl
template<class TypeTag>
struct LinearSolverSplice<TypeTag, TTag::GroundWaterBaseProblem> { using type = TTag::ParallelIstlLinearSolver; };
template<class TypeTag>
struct LinearSolverWrapper<TypeTag, TTag::GroundWaterBaseProblem>
{ using type = Opm::Linear::SolverWrapperConjugatedGradients<TypeTag>; };
} // namespace Opm::Properties
namespace Opm::Parameters {
template<class Scalar>
struct LensLowerLeftX { static constexpr Scalar value = 0.25; };
template<class Scalar>
struct LensLowerLeftY { static constexpr Scalar value = 0.25; };
template<class Scalar>
struct LensLowerLeftZ { static constexpr Scalar value = 0.25; };
template<class Scalar>
struct LensUpperRightX { static constexpr Scalar value = 0.75; };
template<class Scalar>
struct LensUpperRightY { static constexpr Scalar value = 0.75; };
template<class Scalar>
struct LensUpperRightZ { static constexpr Scalar value = 0.75; };
template<class Scalar>
struct Permeability { static constexpr Scalar value = 1e-10; };
template<class Scalar>
struct PermeabilityLens { static constexpr Scalar value = 1e-12; };
} // namespace Opm::Parameters
namespace Opm {
/*!
* \ingroup TestProblems
*
* \brief Test for the immisicible VCVF discretization with only a single phase
*
* This problem is inspired by groundwater flow. Don't expect it to be
* realistic, though: For two dimensions, the domain size is 1m times
* 1m. On the left and right of the domain, no-flow boundaries are
* used, while at the top and bottom free flow boundaries with a
* pressure of 2 bar and 1 bar are used. The center of the domain is
* occupied by a rectangular lens of lower permeability.
*/
template <class TypeTag>
class GroundWaterProblem : public GetPropType<TypeTag, Properties::BaseProblem>
{
using ParentType = GetPropType<TypeTag, Properties::BaseProblem>;
using GridView = GetPropType<TypeTag, Properties::GridView>;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
// copy some indices for convenience
using Indices = GetPropType<TypeTag, Properties::Indices>;
enum {
numPhases = FluidSystem::numPhases,
// Grid and world dimension
dim = GridView::dimension,
dimWorld = GridView::dimensionworld,
// indices of the primary variables
pressure0Idx = Indices::pressure0Idx
};
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
using EqVector = GetPropType<TypeTag, Properties::EqVector>;
using RateVector = GetPropType<TypeTag, Properties::RateVector>;
using BoundaryRateVector = GetPropType<TypeTag, Properties::BoundaryRateVector>;
using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
using Model = GetPropType<TypeTag, Properties::Model>;
using CoordScalar = typename GridView::ctype;
using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
public:
/*!
* \copydoc Doxygen::defaultProblemConstructor
*/
GroundWaterProblem(Simulator& simulator)
: ParentType(simulator)
{ }
/*!
* \copydoc FvBaseProblem::finishInit
*/
void finishInit()
{
ParentType::finishInit();
eps_ = 1.0e-3;
lensLowerLeft_[0] = Parameters::Get<Parameters::LensLowerLeftX<Scalar>>();
if (dim > 1)
lensLowerLeft_[1] = Parameters::Get<Parameters::LensLowerLeftY<Scalar>>();
if (dim > 2)
lensLowerLeft_[2] = Parameters::Get<Parameters::LensLowerLeftY<Scalar>>();
lensUpperRight_[0] = Parameters::Get<Parameters::LensUpperRightX<Scalar>>();
if (dim > 1)
lensUpperRight_[1] = Parameters::Get<Parameters::LensUpperRightY<Scalar>>();
if (dim > 2)
lensUpperRight_[2] = Parameters::Get<Parameters::LensUpperRightY<Scalar>>();
intrinsicPerm_ = this->toDimMatrix_(Parameters::Get<Parameters::Permeability<Scalar>>());
intrinsicPermLens_ = this->toDimMatrix_(Parameters::Get<Parameters::PermeabilityLens<Scalar>>());
}
/*!
* \copydoc FvBaseMultiPhaseProblem::registerParameters
*/
static void registerParameters()
{
ParentType::registerParameters();
Parameters::Register<Parameters::LensLowerLeftX<Scalar>>
("The x-coordinate of the lens' lower-left corner [m].");
Parameters::Register<Parameters::LensUpperRightX<Scalar>>
("The x-coordinate of the lens' upper-right corner [m].");
if (dimWorld > 1) {
Parameters::Register<Parameters::LensLowerLeftY<Scalar>>
("The y-coordinate of the lens' lower-left corner [m].");
Parameters::Register<Parameters::LensUpperRightY<Scalar>>
("The y-coordinate of the lens' upper-right corner [m].");
}
if (dimWorld > 2) {
Parameters::Register<Parameters::LensLowerLeftZ<Scalar>>
("The z-coordinate of the lens' lower-left corner [m].");
Parameters::Register<Parameters::LensUpperRightZ<Scalar>>
("The z-coordinate of the lens' upper-right corner [m].");
}
Parameters::Register<Parameters::Permeability<Scalar>>
("The intrinsic permeability [m^2] of the ambient material.");
Parameters::Register<Parameters::PermeabilityLens<Scalar>>
("The intrinsic permeability [m^2] of the lens.");
Parameters::SetDefault<Parameters::GridFile>("./data/groundwater_2d.dgf");
Parameters::SetDefault<Parameters::EndTime<Scalar>>(1.0);
Parameters::SetDefault<Parameters::InitialTimeStepSize<Scalar>>(1.0);
Parameters::SetDefault<Parameters::EnableGravity>(true);
}
/*!
* \name Problem parameters
*/
// \{
/*!
* \copydoc FvBaseProblem::name
*/
std::string name() const
{
std::ostringstream oss;
oss << "groundwater_" << Model::name();
return oss.str();
}
/*!
* \copydoc FvBaseProblem::endTimeStep
*/
void endTimeStep()
{
#ifndef NDEBUG
this->model().checkConservativeness();
// Calculate storage terms
EqVector storage;
this->model().globalStorage(storage);
// Write mass balance information for rank 0
if (this->gridView().comm().rank() == 0) {
std::cout << "Storage: " << storage << std::endl << std::flush;
}
#endif // NDEBUG
}
/*!
* \copydoc FvBaseMultiPhaseProblem::temperature
*/
template <class Context>
Scalar temperature(const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ return 273.15 + 10; } // 10C
/*!
* \copydoc FvBaseMultiPhaseProblem::porosity
*/
template <class Context>
Scalar porosity(const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ return 0.4; }
/*!
* \copydoc FvBaseMultiPhaseProblem::intrinsicPermeability
*/
template <class Context>
const DimMatrix& intrinsicPermeability(const Context& context,
unsigned spaceIdx,
unsigned timeIdx) const
{
if (isInLens_(context.pos(spaceIdx, timeIdx)))
return intrinsicPermLens_;
else
return intrinsicPerm_;
}
//! \}
/*!
* \name Boundary conditions
*/
//! \{
/*!
* \copydoc FvBaseProblem::boundary
*/
template <class Context>
void boundary(BoundaryRateVector& values, const Context& context,
unsigned spaceIdx, unsigned timeIdx) const
{
const GlobalPosition& globalPos = context.pos(spaceIdx, timeIdx);
if (onLowerBoundary_(globalPos) || onUpperBoundary_(globalPos)) {
Scalar pressure;
Scalar T = temperature(context, spaceIdx, timeIdx);
if (onLowerBoundary_(globalPos))
pressure = 2e5;
else // on upper boundary
pressure = 1e5;
Opm::ImmiscibleFluidState<Scalar, FluidSystem,
/*storeEnthalpy=*/false> fs;
fs.setSaturation(/*phaseIdx=*/0, 1.0);
fs.setPressure(/*phaseIdx=*/0, pressure);
fs.setTemperature(T);
typename FluidSystem::template ParameterCache<Scalar> paramCache;
paramCache.updateAll(fs);
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
fs.setDensity(phaseIdx, FluidSystem::density(fs, paramCache, phaseIdx));
fs.setViscosity(phaseIdx, FluidSystem::viscosity(fs, paramCache, phaseIdx));
}
// impose an freeflow boundary condition
values.setFreeFlow(context, spaceIdx, timeIdx, fs);
}
else {
// no flow boundary
values.setNoFlow();
}
}
//! \}
/*!
* \name Volumetric terms
*/
//! \{
/*!
* \copydoc FvBaseProblem::initial
*/
template <class Context>
void initial(PrimaryVariables& values,
const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{
// const GlobalPosition& globalPos = context.pos(spaceIdx, timeIdx);
values[pressure0Idx] = 1.0e+5; // + 9.81*1.23*(20-globalPos[dim-1]);
}
/*!
* \copydoc FvBaseProblem::source
*/
template <class Context>
void source(RateVector& rate,
const Context& /*context*/,
unsigned /*spaceIdx*/,
unsigned /*timeIdx*/) const
{ rate = Scalar(0.0); }
//! \}
private:
bool onLowerBoundary_(const GlobalPosition& pos) const
{ return pos[dim - 1] < eps_; }
bool onUpperBoundary_(const GlobalPosition& pos) const
{ return pos[dim - 1] > this->boundingBoxMax()[dim - 1] - eps_; }
bool isInLens_(const GlobalPosition& pos) const
{
return lensLowerLeft_[0] <= pos[0] && pos[0] <= lensUpperRight_[0]
&& lensLowerLeft_[1] <= pos[1] && pos[1] <= lensUpperRight_[1];
}
GlobalPosition lensLowerLeft_;
GlobalPosition lensUpperRight_;
DimMatrix intrinsicPerm_;
DimMatrix intrinsicPermLens_;
Scalar eps_;
};
} // namespace Opm
#endif

Some files were not shown because too many files have changed in this diff Show More