mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-11-21 16:57:25 -06:00
doc: (almost) finish the design patterns chapter in the handbook
also remove the ReferenceElements property because changing to the old DUNE entity numbering would not work anyways...
This commit is contained in:
parent
99e13c14fe
commit
02ddfea028
8053
doc/handbook/EPS/car-hierarchy.eps
Normal file
8053
doc/handbook/EPS/car-hierarchy.eps
Normal file
File diff suppressed because it is too large
Load Diff
11676
doc/handbook/EPS/car-propertynames.eps
Normal file
11676
doc/handbook/EPS/car-propertynames.eps
Normal file
File diff suppressed because it is too large
Load Diff
554
doc/handbook/SVG/car-hierarchy.svg
Normal file
554
doc/handbook/SVG/car-hierarchy.svg
Normal 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 |
820
doc/handbook/SVG/car-propertynames.svg
Normal file
820
doc/handbook/SVG/car-propertynames.svg
Normal 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 |
@ -866,8 +866,23 @@
|
||||
key = {DUNE}
|
||||
}
|
||||
|
||||
@MISC{FENICS-HP,
|
||||
title = {The {FEniCS} Project: \url{http://www.fenicsproject.org/}},
|
||||
key = {FENICS}
|
||||
}
|
||||
|
||||
@MISC{STL-REF-HP,
|
||||
title = {A {STL} Reference: \url{http://www.cplusplus.com/reference/stl/}},
|
||||
key = {STL}
|
||||
}
|
||||
|
||||
@MISC{BOOST-HP,
|
||||
title = {The {Boost} Homepage: \url{http://www.boost.org/}},
|
||||
key = {BOOST}
|
||||
}
|
||||
|
||||
@MISC{UG-HP,
|
||||
title = {The {UG} Homepage: \url{http://sit.iwr.uni-heidelberg.de/~ug/}},
|
||||
title = {The {UG} Homepage: \url{http://atlas.gcsc.uni-frankfurt.de/~ug/}},
|
||||
key = {UG}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
\usepackage{lscape}
|
||||
\usepackage{enumerate}
|
||||
\usepackage{rotating}
|
||||
\usepackage{subfig}
|
||||
|
||||
|
||||
\DeclareGraphicsExtensions{.eps, .jpg}
|
||||
|
@ -1,29 +1,108 @@
|
||||
\chapter{The \Dumux Property System}
|
||||
\label{sec:propertysytem}
|
||||
\chapter{\Dumux Design Patterns}
|
||||
\label{chap:DesignPatterns}
|
||||
|
||||
This chapter tries to give high-level understanding of the motivation
|
||||
for the \Dumux property system and how to use it. First, an
|
||||
introduction to polymorphism is given. After this, the fundamental
|
||||
motivation and the ideas behind the \Dumux property system are
|
||||
highlighted and the implementation is outlined from a high-level
|
||||
This chapter tries to give high-level understanding of some of the
|
||||
fundamental techniques which are used by \Dumux and the motivation
|
||||
behind these design decisions. It is assumed that the reader already
|
||||
posseses some basic knowledge in object oriented programming with C++.
|
||||
|
||||
First, a quick motivation of C++ template programming is given. Then
|
||||
follows an introduction to polymorphism and the opportunities for it
|
||||
opened by the template mechanism. After that, there is a look at some
|
||||
drawbacks associated with template programming. One of these drawbacks
|
||||
-- deep nesting of template parameters -- motivates the \Dumux
|
||||
property system which, in this chapter is outlined from the user
|
||||
perspective. The chapter concludes with a simple example of how to use
|
||||
the \Dumux property system.
|
||||
|
||||
\section{C++ Template Programming}
|
||||
|
||||
One of the main features of modern versions of the C++ language is
|
||||
robust support for templates. Templates are a mechanism for code
|
||||
generation build directly into the compiler. To see the motivation of
|
||||
templates, consider a linked list of \texttt{double} values which
|
||||
could be implemented like this:
|
||||
\begin{verbatim}
|
||||
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{verbatim}
|
||||
But what if a list of strings is also required? The only ``clean'' way
|
||||
to achive this without templates would be to copy
|
||||
\texttt{DoubleListNode}, then rename it and change the type of the
|
||||
\texttt{value} attribute. It should be clear that this is a very
|
||||
cumbersome and error-prone process, so recent standards of the C++
|
||||
programming language provide the template mechanism, which is a way
|
||||
let the compiler do the tedious work. Using templates, a generic
|
||||
linked list can be implemented like this:
|
||||
\begin{verbatim}
|
||||
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{verbatim}
|
||||
|
||||
Compared to code generation approaches using external tools -- which
|
||||
is the approach chosen for example by the FEniCS~\cite{FENICS-HP}
|
||||
project -- or heavy use of the C preprocessor -- as done for example
|
||||
within the UG framework~\cite{UG-HP} -- the template approach has
|
||||
several advantages:
|
||||
\begin{description}
|
||||
\item[Well Programmable:] Programming errors are directly detected by
|
||||
the C++ compiler and compiler messages also yield useful information
|
||||
since the actual source code is visible to the developer and not
|
||||
obfuscated by macros or code generation.
|
||||
\item[Easily Debugable:] Programs which use the template mechanism can be
|
||||
debugged almost as easily as C++ 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 \Dumux 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 C++ standard and functionality provided by the
|
||||
quasi-standard Boost~\cite{BOOST-HP} libraries.
|
||||
|
||||
\section{Polymorphism}
|
||||
|
||||
In object oriented programming, it often happens that some
|
||||
functionality make sense for all classes in a hierarchy, but what
|
||||
actually need to be \textit{done} can be quite different. This
|
||||
observation gives rise to \textit{polymorphism}. In polymorphism, a
|
||||
call to an object's method \textit{means} the same thing, but how this
|
||||
method is \textit{implemented} is case specific\footnote{This
|
||||
\textit{poly} of polymorphism: There are multiple ways to achieve
|
||||
the same goal.}.
|
||||
In object oriented programming, some functionality often makes sense
|
||||
for all classes in a hierarchy, but what actually needs to be
|
||||
\textit{done} can differ for each concrete class. This observation
|
||||
motivates \textit{polymorphism}. Fundamentally, polymorphism is all
|
||||
techniques where 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 \textit{poly} of polymorphism: There are
|
||||
multiple ways to achieve the same goal.}.
|
||||
|
||||
In C++, there are two common approaches to polymorphism: The
|
||||
traditional -- i.e. non-template programming -- dynamic polymorphism,
|
||||
and static polymorphism which is made possible by template
|
||||
programming.
|
||||
In C++, there are two common ways to achieve polymorphism: The
|
||||
traditional dynamic polymorphism which is not based on template
|
||||
programming, and static polymorphism which is only made possible by
|
||||
template programming.
|
||||
|
||||
\subsection*{Dynamic Polymorphism}
|
||||
|
||||
@ -36,8 +115,8 @@ of each method which is declared virtual. If such a method is called
|
||||
on an object, the compiler generates code which retrieves the method's
|
||||
address from the object's \texttt{vtable} and then calls it. This
|
||||
explains why this mechanism is called \textbf{dynamic} polymorphism:
|
||||
the methods which are actually called are dynamically determined at
|
||||
run time.
|
||||
the code which is actually called are dynamically determined at run
|
||||
time.
|
||||
|
||||
\begin{example}
|
||||
\label{example:DynPoly}
|
||||
@ -63,7 +142,7 @@ class Car
|
||||
|
||||
double range(double fuelTankFillLevel)
|
||||
{ return 100*fuelTankFillLevel*fuelTankSize()/gasUsage(); }
|
||||
}
|
||||
};
|
||||
\end{verbatim}
|
||||
|
||||
Actual car models can now derived from the base class:
|
||||
@ -73,14 +152,14 @@ 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{verbatim}
|
||||
|
||||
The \text{range} method called on the base class yields correct result
|
||||
@ -93,13 +172,12 @@ int main()
|
||||
{
|
||||
Lupo lupo;
|
||||
S s;
|
||||
std::cout << "VW Lupo:"
|
||||
std::cout << "VW Lupo:";
|
||||
std::cout << "Median range: " << lupo.range(0.50) << "\n";
|
||||
printMaxRange(lupo);
|
||||
std::cout << "Mercedes S-Class:"
|
||||
std::cout << "Mercedes S-Class:";
|
||||
std::cout << "Median range: " << s.range(0.50) << "\n";
|
||||
printMaxRange(s);
|
||||
return 0;
|
||||
}
|
||||
\end{verbatim}
|
||||
|
||||
@ -123,27 +201,28 @@ What happens if \dots
|
||||
|
||||
\subsection*{Static Polymorphism}
|
||||
|
||||
Static polymorphism has a few disadvantages, probably the most
|
||||
Dynamic polymorphism has a few disadvantages, probably the most
|
||||
relevant in the context of \Dumux is that the compiler can not see
|
||||
``inside'' the called methods and thus cannot properly optimize
|
||||
them. For example modern C++ compilers 'inline' short methods, that is
|
||||
they copy the body the function body to where it is called which saves
|
||||
a few instructions as well as allows further optimizations across the
|
||||
function call. Inlining and other cross call optimizations are next to
|
||||
impossible in conjunction with dynamic polymorphism, since these
|
||||
``inside'' the called methods and thus cannot properly optimize. For
|
||||
example modern C++ compilers 'inline' short methods, i.e. they copy
|
||||
the body the method's body to where it is called. This allows to save
|
||||
a few instructions as well as enables further optimizations which may
|
||||
depend on specific properties of the function arguments (e.g. constant
|
||||
value elimination, etc). Inlining and other cross-method optimizations
|
||||
are next to impossible when using dynamic polymorphism, since these
|
||||
techniques need to be done by the compiler (i.e. at compile time)
|
||||
while the actual code which gets called is only determined at run time
|
||||
for virtual methods. To overcome this issue, template programming
|
||||
allows a compile time polymorphism. This scheme works by supplying an
|
||||
additional template parameter to the base class which specifies the
|
||||
type of the derived class. Whenever the base class needs to call back
|
||||
at the derived class, the memory of the current object is
|
||||
while, for virtual methods, the actual code that gets executed is
|
||||
determined at run time. 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 a derived object and the method is then called. This
|
||||
scheme gives the C++ compiler complete transparency of the code
|
||||
executed and thus opens for much better optimization
|
||||
oportunities. Also, since this mechanism completely happens at compile
|
||||
time, it is called ``static polymorphism'' because the called method
|
||||
cannot be changed dynamically at runtime.
|
||||
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 changed
|
||||
dynamically at runtime.
|
||||
\begin{example}
|
||||
Using static polymorphism, the base class of example \ref{example:DynPoly}
|
||||
can be written as
|
||||
@ -156,17 +235,15 @@ class Car
|
||||
double gasUsage()
|
||||
{ return 4.5; };
|
||||
double fuelTankSize()
|
||||
{ throw "The derived class needs to implement the fuelTankSize() method" };
|
||||
{ throw "The derived class needs to implement the fuelTankSize() method"; };
|
||||
|
||||
double range(double fuelTankFillLevel)
|
||||
{ return 100*fuelTankFillLevel*asImp_().fuelTankSize()/asImp_().gasUsage(); }
|
||||
|
||||
protected:
|
||||
// reinterpret the 'this' object as an object of type 'Imp'
|
||||
// reinterpret 'this' as a pointer to an object of type 'Imp'
|
||||
Imp &asImp_() { return *static_cast<Imp*>(this); }
|
||||
// version for constant 'this' objects
|
||||
const Imp &asImp_() const { return *static_cast<const Impl*>(this); }
|
||||
}
|
||||
};
|
||||
\end{verbatim}
|
||||
(Note the \texttt{asImp\_()} calls in the \texttt{range} method.)
|
||||
|
||||
@ -177,14 +254,14 @@ 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{verbatim}
|
||||
\end{example}
|
||||
|
||||
@ -199,10 +276,10 @@ int main()
|
||||
{
|
||||
Lupo lupo;
|
||||
S s;
|
||||
std::cout << "VW Lupo:"
|
||||
std::cout << "VW Lupo:";
|
||||
std::cout << "Median range: " << lupo.range(0.50) << "\n";
|
||||
printMaxRange(lupo);
|
||||
std::cout << "Mercedes S-Class:"
|
||||
std::cout << "Mercedes S-Class:";
|
||||
std::cout << "Median range: " << s.range(0.50) << "\n";
|
||||
printMaxRange(s);
|
||||
return 0;
|
||||
@ -211,87 +288,418 @@ int main()
|
||||
|
||||
\textbf{TODO: Exercise}
|
||||
|
||||
\subsection*{Explosion of Template Arguments}
|
||||
\section{Common Template Programming Related Problems}
|
||||
|
||||
A major drawback with template programming in general and with static
|
||||
polymorphism in particular is that the template arguments required for
|
||||
the base class tend to explode quickly. This is due to the fact that
|
||||
often template arguments are often used as arguments for other
|
||||
template classes. To demonstrate this point consider the local
|
||||
jacobian class of the two-phase, two-component box model before the
|
||||
\Dumux property system was introduced:
|
||||
Although C++ template programming opens a few intriguing
|
||||
possibilities, it also has a few disadvantages. In this section a few
|
||||
of those are outlined and some hints how they can be dealt with are
|
||||
provided.
|
||||
|
||||
\subsection*{Blow-Up of Identifiers}
|
||||
|
||||
One particular problem with advanced use of templates is that the full
|
||||
identifier names for types and methods quickly become really long and
|
||||
unreadable. For example a typical line of an error message generated
|
||||
using GCC 4.5 in conjunction with \Dune-PDELab looks like
|
||||
\begin{verbatim}
|
||||
template<class ProblemT, class BoxTraitsT, class TwoPTwoCTraitsT>
|
||||
class TwoPTwoCBoxJacobian
|
||||
: public TwoPTwoCBoxJacobianBase<
|
||||
ProblemT,
|
||||
BoxTraitsT,
|
||||
TwoPTwoCTraitsT,
|
||||
TwoPTwoCElementData<TwoPTwoCTraitsT,ProblemT>,
|
||||
TwoPTwoCVertexData<TwoPTwoCTraitsT,ProblemT>,
|
||||
TwoPTwoCFluxData<TwoPTwoCTraitsT,
|
||||
ProblemT,
|
||||
TwoPTwoCVertexData<TwoPTwoCTraitsT,
|
||||
ProblemT> >,
|
||||
TwoPTwoCBoxJacobian<ProblemT,
|
||||
BoxTraitsT,
|
||||
TwoPTwoCTraitsT> >
|
||||
{
|
||||
// ...
|
||||
}
|
||||
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, Dumux::PDELab::BoxISTLVectorBackend<Dumux::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, Dumux::PDELab::\
|
||||
BoxISTLVectorBackend<Dumux::Properties::TTag::LensProblem> >, 2, Dune::\
|
||||
PDELab::GridFunctionSpaceBlockwiseMapper>, Dumux::PDELab::BoxLocalOperator\
|
||||
<Dumux::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{verbatim}
|
||||
This seriously complicates diagnostics. Although there is no full
|
||||
solution for this problem yet, an effective way of dealing with such
|
||||
kinds of error messages is to ignore the type information and to just
|
||||
go to the location given at the beginning of the line and also
|
||||
consider the error text. If nested templates are used and the given
|
||||
location looks well, the lines above the actual error specify how
|
||||
exactly the code was instantiated by the compiler (the lines starting
|
||||
with \texttt{instantiated from}). In this case it is advisable to look
|
||||
at the innermost location of the code which has been most recently
|
||||
added.
|
||||
|
||||
\subsection*{Proliferation of Template Parameters}
|
||||
|
||||
Writing flexible templates often requires a large -- and in some cases
|
||||
even unknown -- number of template parameters. As an example, the type
|
||||
of the global operator space from \Dune-PDELab which produced the error
|
||||
message above is specified like this:
|
||||
\begin{verbatim}
|
||||
enum {numEq = 2};
|
||||
enum {dim = 2};
|
||||
typedef Dune::UGGrid<2> 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, Dumux::PDELab::BoxISTLVectorBackend<TypeTag>
|
||||
>
|
||||
doubleGridFunctionSpace;
|
||||
typedef Dune::PDELab::PowerGridFunctionSpace<
|
||||
doubleGridFunctionSpace,
|
||||
numEq,
|
||||
Dune::PDELab::GridFunctionSpaceBlockwiseMapper
|
||||
>
|
||||
GridFunctionSpace;
|
||||
typedef typename GridFunctionSpace::ConstraintsContainer<double>::Type
|
||||
ConstraintsTrafo;
|
||||
typedef Dumux::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{verbatim}
|
||||
|
||||
Although the code above is not really intuitive, it is not a big
|
||||
problem if the type in case the grid operator space is only required
|
||||
at exactly one location. If, on the other hand, it needs to be
|
||||
consistend over many locations in the source code, something has to be
|
||||
done in order to keep the code maintainable. The next section outlines
|
||||
approaches on how to tackle this particular problem.
|
||||
|
||||
% \begin{frame}[fragile]
|
||||
% \frametitle{Nested template arguments}
|
||||
\section{The \Dumux Property System}
|
||||
\label{sec:propertysystem}
|
||||
|
||||
% One problem of static Polymorphism:
|
||||
% \begin{itemize}
|
||||
% \item Template arguments often also require template parameters
|
||||
% \item ``Implementation'' arguments are especially nasty:
|
||||
% \begin{itemize}
|
||||
% \item Assume a base class Base<A, B, Imp>
|
||||
% \item Assume a class Derived<B> and that A is C< Derived<B> >
|
||||
% \item To specify Derived:
|
||||
% \end{itemize}
|
||||
% \end{itemize}
|
||||
% {\scriptsize
|
||||
% \begin{verbatim}
|
||||
% template <class B>
|
||||
% class Derived : public Base< C<Derived<B> >, B, Derived<B> >
|
||||
% \end{verbatim}
|
||||
% }
|
||||
% \end{frame}
|
||||
This section is dedicated to means on how to solve the problem of
|
||||
template argument proliferation. First, a short look on the more
|
||||
traditional approach using traits classes is taken, then the design of
|
||||
the \Dumux property system is explained and finally a short example on
|
||||
how the system can be used is given.
|
||||
|
||||
% \begin{frame}[fragile]
|
||||
% \frametitle{A real-world example}
|
||||
\subsection*{Traits Classes}
|
||||
|
||||
% {\scriptsize
|
||||
% }
|
||||
% \end{frame}
|
||||
A classic approach to reduce the number of template parameters is to
|
||||
gather the all arguments in a special class, a so-called traits
|
||||
class. For example instead of writing
|
||||
\begin{verbatim}
|
||||
template <class A, class B, class C, class D>
|
||||
class MyClass {};
|
||||
\end{verbatim}
|
||||
one can use
|
||||
\begin{verbatim}
|
||||
template <class Traits>
|
||||
class MyClass {};
|
||||
\end{verbatim}
|
||||
where the \texttt{Traits} class contains public type definitions for
|
||||
\texttt{A}, \texttt{B}, \texttt{C} and \texttt{D}, e.g.
|
||||
\begin{verbatim}
|
||||
struct MyTraits
|
||||
{
|
||||
typedef float A;
|
||||
typedef double B;
|
||||
typedef short C;
|
||||
typedef int D;
|
||||
};
|
||||
\end{verbatim}
|
||||
|
||||
% \begin{frame}[fragile]
|
||||
% \frametitle{Traits}
|
||||
|
||||
% A possible solution is to specify a class which specifies the
|
||||
% template parameters as type definitions (often called a Traits
|
||||
% class): {\scriptsize
|
||||
% \begin{verbatim}
|
||||
% class Traits
|
||||
% { public:
|
||||
% typedef int A;
|
||||
% typedef C<A> B;
|
||||
% };
|
||||
As there is no a free lunch, the traits approach comes with a few
|
||||
disadvantages of its own:
|
||||
\begin{enumerate}
|
||||
\item Trait class hierarchies are problematic. This is due to the fact
|
||||
that type defintions must always be defined for the lowest level
|
||||
traits class if it is to be used by higher level classes.
|
||||
\item Traits quickly lead to circular dependencies. This implies that
|
||||
types can not be extracted from classes which get the trait class as
|
||||
an argument.
|
||||
\end{enumerate}
|
||||
|
||||
% template <class Traits, class Implementation>
|
||||
% class Base {};
|
||||
To see the point of the first issue, consider the following example:
|
||||
\begin{verbatim}
|
||||
struct MyBaseTraits {
|
||||
typedef int Scalar;
|
||||
typedef std::vector<Scalar> Vector;
|
||||
};
|
||||
|
||||
% template <class Traits>
|
||||
% class Derived : public class Base<Traits, Derived<Traits>
|
||||
% {};
|
||||
% \end{verbatim}
|
||||
% }
|
||||
struct MyDerivedTraits : public MyBaseTraits {
|
||||
typedef double Scalar;
|
||||
};
|
||||
|
||||
int main() {
|
||||
MyDerivedTraits::Vector v{1.41421, 1.73205, 2};
|
||||
for (int i = 0; i < v.size(); ++i)
|
||||
std::cout << v[i]*v[i] << std::endl;
|
||||
}
|
||||
\end{verbatim}
|
||||
Contrary to what is wanted, the \texttt{v} variable is a vector of
|
||||
integers. In this case, static polymorphsism does not come to rescue,
|
||||
since it would lead to a dependency cycle between
|
||||
\texttt{MyBaseTraits} and \texttt{MyDerivedTraits}.
|
||||
|
||||
The second point is illuminated by the following example, where one
|
||||
would expect the \texttt{MyTraits::\-VectorType} to be \texttt{std::vector<double>}:
|
||||
\begin{verbatim}
|
||||
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{verbatim}
|
||||
Although this example seems to be quite pathetic, it is often useful
|
||||
in reality to specify parameters in such a way.
|
||||
|
||||
\subsection*{Features of the \Dumux Property System}
|
||||
|
||||
To get around the issues with traits classes, the \Dumux property
|
||||
system was designed. It can be seen as a traits system which allows
|
||||
easy type inheritance and any acyclic dependency of types. The scope
|
||||
at which the property system is executed is completely compile
|
||||
time. It is based on the following concepts:
|
||||
\begin{itemize}
|
||||
\item[Property:] In the context of the \Dumux 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:] Properties can be arranged in
|
||||
hierarchies, just like normal classes. Each in the context of the
|
||||
\Dumux property system the nodes in the inhertitance hierarchy on
|
||||
which the property is defined are called \textbf{type tags}.
|
||||
\item[Property Nesting:] The definition of a property can depend on
|
||||
the value of other properties (as long as there are no cyclic
|
||||
dependencies).
|
||||
\item[Introspection:] The \Dumux property systems supports
|
||||
\textbf{diagnostic messages} which can be used to find out how a
|
||||
certain property was inherited and where it was defined.
|
||||
\end{itemize}
|
||||
|
||||
\subsection*{\Dumux Property System Reference}
|
||||
|
||||
All files where the \Dumux property system is utilized should include
|
||||
the header file \texttt{dumux/common/propertysystem.hh}, declaration
|
||||
of new type tags and property tags as well as property definitions
|
||||
must be done inside the namespace \texttt{Dumux::Properties}.
|
||||
|
||||
\subsection*{Defining Type Tags}
|
||||
|
||||
New nodes in the type tag hierarchy can be defined using
|
||||
\begin{verbatim}
|
||||
NEW_TYPE_TAG(NewTypeTagName, INHERITS_FROM(BaseTagName1, BaseTagName2, ...));
|
||||
\end{verbatim}
|
||||
where the \texttt{INHERITS\_FROM} part is optional. To avoid
|
||||
inconsistencies in the hierarchy, type tags may only be defined
|
||||
exactly once in the whole program.
|
||||
|
||||
\subsubsection*{Declaring Property Tags}
|
||||
|
||||
New property tags -- i.e. labels for properties -- are be declared
|
||||
using
|
||||
\begin{verbatim}
|
||||
NEW_PROP_TAG(NewPropTagName);
|
||||
\end{verbatim}
|
||||
A property tag can be declared arbitrarily often inside a program, in
|
||||
fact it is recomended that all properties are declared in each file
|
||||
where they are used.
|
||||
|
||||
\subsubsection*{Defining Properties}
|
||||
|
||||
The actual value of a property on a given node of the type tag
|
||||
hierarchy is defined using
|
||||
\begin{verbatim}
|
||||
SET_PROP(TypeTagName, PropertyTagName)
|
||||
{
|
||||
// arbitrary body of a struct
|
||||
};
|
||||
\end{verbatim}
|
||||
For each a program, a property itself can be declared at most once,
|
||||
although properties may be overwritten at derived type tags.
|
||||
|
||||
Also, the following convenience macros available to define simple
|
||||
properties:
|
||||
\begin{verbatim}
|
||||
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{verbatim}
|
||||
|
||||
\subsubsection*{Unsetting Properties}
|
||||
|
||||
\subsubsection*{Converting Tag Names to Tag Types}
|
||||
|
||||
For the C++ compiler property and type tags look like ordinary
|
||||
types. Both can thus be used as template or function arguments,
|
||||
etc. To convert the name of a property tag or a type tag into the
|
||||
corrosponding type, the macros \texttt{TTAG(TypeTagName)} and
|
||||
\texttt{PTAG(PropertyTagName)} ought to be used.
|
||||
|
||||
\subsubsection*{Retrieving Property Values}
|
||||
|
||||
\begin{verbatim}
|
||||
GET_PROP(TypeTag, PropertyTag)
|
||||
\end{verbatim}
|
||||
|
||||
Convenience macros:
|
||||
\begin{verbatim}
|
||||
GET_PROP_TYPE(TypeTag, PropertyTag)
|
||||
GET_PROP_VALUE(TypeTag, PropertyTag)
|
||||
\end{verbatim}
|
||||
|
||||
\subsubsection*{Nesting Property definitions}
|
||||
|
||||
\subsection*{A Simple 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 derive the shared properties 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 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 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 \Dumux property system, the inheritance hierarchy can be
|
||||
defined using
|
||||
\begin{verbatim}
|
||||
namespace Dumux {
|
||||
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{verbatim}
|
||||
|
||||
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{verbatim}
|
||||
namespace Dumux {
|
||||
namespace Properties {
|
||||
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{verbatim}
|
||||
|
||||
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 $l/100km$
|
||||
times $30$, the number of seats is $5$ and the gas usage is
|
||||
$4\;l/100km$.
|
||||
\item A truck is by law limited to $100\;km/h$ top speed, the number
|
||||
of seats is $2$, it uses $18\;l/100km$ and has a cargo payload of
|
||||
$35\;t$.
|
||||
\item A tank exhibits a top speed of $60\;km/h$, uses $65\;l/100km$
|
||||
and features a $120\;mm$ diameter canon
|
||||
\item A sedan has a gas usage of $7\;l/100km$, as well as an automatic
|
||||
transmission, in every other aspect it is like for a compact car.
|
||||
\item A pick-up truck has a top speed of $120\;km/h$ and a payload of
|
||||
$5\;t$. In every other aspect it is like 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}
|
||||
|
||||
Using the \Dumux property system, these characteristics can be
|
||||
expressed using
|
||||
\begin{verbatim}
|
||||
namespace Dumux {
|
||||
namespace Properties {
|
||||
SET_INT_PROP(CompactCar, TopSpeed, GET_PROP_VALUE(TypeTag, PTAG(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), PTAG(TopSpeed)));
|
||||
}}
|
||||
\end{verbatim}
|
||||
|
||||
At this point, the Hummer-H1 has a $120\;mm$ canon which it inherited
|
||||
from its military ancestor. It can be removed by
|
||||
\begin{verbatim}
|
||||
namespace Dumux {
|
||||
namespace Properties {
|
||||
UNSET_PROP(HummerH1, CanonCaliber);
|
||||
}}
|
||||
\end{verbatim}
|
||||
|
||||
Now the hierarchy can be queried and some diagnostic messages can be
|
||||
generated. For example
|
||||
\begin{verbatim}
|
||||
int main()
|
||||
{
|
||||
std::cout << "top speed of sedan: " << GET_PROP_VALUE(TTAG(Sedan), PTAG(TopSpeed)) << "\n";
|
||||
std::cout << "top speed of truck: " << GET_PROP_VALUE(TTAG(Truck), PTAG(TopSpeed)) << "\n";
|
||||
|
||||
std::cout << PROP_DIAGNOSTIC(TTAG(Sedan), PTAG(TopSpeed));
|
||||
std::cout << PROP_DIAGNOSTIC(TTAG(HummerH1), PTAG(CanonCaliber));
|
||||
}
|
||||
\end{verbatim}
|
||||
will yield in the following output:
|
||||
\begin{verbatim}
|
||||
top speed of sedan: 210
|
||||
top speed of truck: 100
|
||||
Property 'TopSpeed' for type tag 'Sedan'
|
||||
inherited from 'CompactCar'
|
||||
defined at test_propertysystem.cc:90
|
||||
Property 'CanonCaliber' for type tag 'HummerH1'
|
||||
explicitly unset at test_propertysystem.cc:113
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
%%% Local Variables:
|
||||
|
@ -31,8 +31,7 @@ int main(int argc, char** argv)
|
||||
{
|
||||
try {
|
||||
typedef TTAG(TutorialProblemCoupled) TypeTag; /*@\label{tutorial-coupled:set-type-tag}@*/
|
||||
typedef GET_PROP_TYPE(TypeTag, PTAG(Scalar)) Scalar; /*@\label{tutorial-coupled:retrieve-types-begin}@*/
|
||||
typedef GET_PROP_TYPE(TypeTag, PTAG(Grid)) Grid;
|
||||
typedef GET_PROP_TYPE(TypeTag, PTAG(Grid)) Grid; /*@\label{tutorial-coupled:retrieve-types-begin}@*/
|
||||
typedef GET_PROP_TYPE(TypeTag, PTAG(TimeManager)) TimeManager;
|
||||
typedef GET_PROP_TYPE(TypeTag, PTAG(Problem)) Problem; /*@\label{tutorial-coupled:retrieve-types-end}@*/
|
||||
|
||||
|
@ -88,7 +88,7 @@ int main(int argc, char** argv)
|
||||
|
||||
Problem problem(gridPtr->leafView()); /*@\label{tutorial-decoupled:instantiate-problem}@*/
|
||||
|
||||
// load restart file if necessarry
|
||||
// load restart file if necessary
|
||||
if (restart) /*@\label{tutorial-decoupled:restart}@*/
|
||||
problem.deserialize(restartTime);
|
||||
|
||||
|
@ -17,17 +17,13 @@
|
||||
#ifndef DUMUX_TUTORIALPROBLEM_COUPLED_HH
|
||||
#define DUMUX_TUTORIALPROBLEM_COUPLED_HH
|
||||
|
||||
// fluid properties
|
||||
#include <dumux/material/fluidsystems/2p_system.hh>
|
||||
|
||||
// the numerical model
|
||||
#include <dumux/boxmodels/2p/2pmodel.hh>
|
||||
|
||||
// the grid used
|
||||
#include <dune/grid/yaspgrid.hh>
|
||||
#include <dune/grid/io/file/dgfparser/dgfs.hh>
|
||||
// the DUNE grid used
|
||||
#include <dune/grid/sgrid.hh>
|
||||
|
||||
// assign parameters dependent on space (e.g. spatial parameters)
|
||||
// spatialy dependent parameters
|
||||
#include "tutorialspatialparameters_coupled.hh"
|
||||
|
||||
namespace Dumux
|
||||
@ -44,9 +40,7 @@ NEW_TYPE_TAG(TutorialProblemCoupled, INHERITS_FROM(BoxTwoP)); /*@\label{tutorial
|
||||
|
||||
// Set the "Problem" property
|
||||
SET_PROP(TutorialProblemCoupled, Problem) /*@\label{tutorial-coupled:set-problem}@*/
|
||||
{
|
||||
typedef Dumux::TutorialProblemCoupled<TTAG(TutorialProblemCoupled)> type;
|
||||
};
|
||||
{ typedef Dumux::TutorialProblemCoupled<TypeTag> type;};
|
||||
|
||||
// Set the grid
|
||||
SET_PROP(TutorialProblemCoupled, Grid) /*@\label{tutorial-coupled:set-grid}@*/
|
||||
@ -71,61 +65,49 @@ SET_PROP(TutorialProblemCoupled, Grid) /*@\label{tutorial-coupled:set-grid}@*/
|
||||
// Set the wetting phase
|
||||
SET_PROP(TutorialProblemCoupled, WettingPhase) /*@\label{tutorial-coupled:2p-system-start}@*/
|
||||
{
|
||||
private:
|
||||
typedef typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)) Scalar;
|
||||
public:
|
||||
typedef Dumux::LiquidPhase<Scalar, Dumux::H2O<Scalar> > type; /*@\label{tutorial-coupled:wettingPhase}@*/
|
||||
private: typedef typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)) Scalar;
|
||||
public: typedef Dumux::LiquidPhase<Scalar, Dumux::H2O<Scalar> > type; /*@\label{tutorial-coupled:wettingPhase}@*/
|
||||
};
|
||||
|
||||
// Set the non-wetting phase
|
||||
SET_PROP(TutorialProblemCoupled, NonwettingPhase)
|
||||
{
|
||||
private:
|
||||
typedef typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)) Scalar;
|
||||
public:
|
||||
typedef Dumux::LiquidPhase<Scalar, Dumux::Oil<Scalar> > type; /*@\label{tutorial-coupled:nonwettingPhase}@*/
|
||||
private: typedef typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)) Scalar;
|
||||
public: typedef Dumux::LiquidPhase<Scalar, Dumux::Oil<Scalar> > type; /*@\label{tutorial-coupled:nonwettingPhase}@*/
|
||||
}; /*@\label{tutorial-coupled:2p-system-end}@*/
|
||||
|
||||
|
||||
// Set the spatial parameters
|
||||
SET_PROP(TutorialProblemCoupled, SpatialParameters) /*@\label{tutorial-coupled:set-spatialparameters}@*/
|
||||
{
|
||||
typedef Dumux::TutorialSpatialParametersCoupled<TypeTag> type;
|
||||
};
|
||||
{ typedef Dumux::TutorialSpatialParametersCoupled<TypeTag> type; };
|
||||
|
||||
// Disable gravity
|
||||
SET_BOOL_PROP(TutorialProblemCoupled, EnableGravity, false); /*@\label{tutorial-coupled:gravity}@*/
|
||||
}
|
||||
|
||||
// Definition of the actual problem
|
||||
template <class TypeTag = TTAG(TutorialProblemCoupled) >
|
||||
template <class TypeTag>
|
||||
class TutorialProblemCoupled : public TwoPProblem<TypeTag> /*@\label{tutorial-coupled:def-problem}@*/
|
||||
{
|
||||
typedef TutorialProblemCoupled<TypeTag> ThisType;
|
||||
typedef TwoPProblem<TypeTag> ParentType;
|
||||
typedef typename GET_PROP_TYPE(TypeTag, PTAG(GridView)) GridView;
|
||||
typedef typename GET_PROP_TYPE(TypeTag, PTAG(TimeManager)) TimeManager;
|
||||
|
||||
// Grid and world dimension
|
||||
enum {
|
||||
dim = GridView::dimension,
|
||||
dimWorld = GridView::dimensionworld,
|
||||
};
|
||||
|
||||
typedef typename GridView::Grid::ctype CoordScalar;
|
||||
typedef typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)) Scalar;
|
||||
typedef typename GET_PROP_TYPE(TypeTag, PTAG(GridView)) GridView;
|
||||
|
||||
typedef typename GET_PROP_TYPE(TypeTag, PTAG(TwoPIndices)) Indices;
|
||||
// Grid dimension
|
||||
enum { dim = GridView::dimension };
|
||||
|
||||
// Types from DUNE-Grid
|
||||
typedef typename GridView::template Codim<0>::Entity Element;
|
||||
typedef typename GridView::template Codim<dim>::Entity Vertex;
|
||||
typedef typename GridView::Intersection Intersection;
|
||||
typedef Dune::FieldVector<CoordScalar, dim> LocalPosition;
|
||||
typedef Dune::FieldVector<CoordScalar, dimWorld> GlobalPosition;
|
||||
typedef Dune::FieldVector<Scalar, dim> GlobalPosition;
|
||||
|
||||
// Dumux specific types
|
||||
typedef typename GET_PROP_TYPE(TypeTag, PTAG(TimeManager)) TimeManager;
|
||||
typedef typename GET_PROP_TYPE(TypeTag, PTAG(TwoPIndices)) Indices;
|
||||
typedef typename GET_PROP_TYPE(TypeTag, PTAG(PrimaryVariables)) PrimaryVariables;
|
||||
typedef typename GET_PROP_TYPE(TypeTag, PTAG(BoundaryTypes)) BoundaryTypes;
|
||||
typedef typename GET_PROP_TYPE(TypeTag, PTAG(FVElementGeometry)) FVElementGeometry;
|
||||
typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
|
||||
|
||||
public:
|
||||
TutorialProblemCoupled(TimeManager &timeManager,
|
||||
@ -133,37 +115,35 @@ public:
|
||||
: ParentType(timeManager, gridView)
|
||||
{
|
||||
// initialize the tables of the fluid system
|
||||
FluidSystem::init();
|
||||
GET_PROP_TYPE(TypeTag, PTAG(FluidSystem))::init();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The problem name.
|
||||
*
|
||||
* This is used as a prefix for files generated by the simulation.
|
||||
*/
|
||||
// Specified the problem name. This is used as a prefix for files
|
||||
// generated by the simulation.
|
||||
const char *name() const
|
||||
{ return "tutorial_coupled"; }
|
||||
|
||||
// Return the temperature within the domain. We use 10 degrees Celsius.
|
||||
// Return the temperature within a finite volume. We use constant
|
||||
// 10 degrees Celsius.
|
||||
Scalar temperature(const Element &element,
|
||||
const FVElementGeometry &fvElemGeom,
|
||||
int scvIdx) const
|
||||
{ return 283.15; };
|
||||
|
||||
// Specifies which kind of boundary condition should be used for
|
||||
// which equation on a given boundary segment.
|
||||
void boundaryTypes(BoundaryTypes &BCtype, const Vertex &vertex) const
|
||||
// which equation for a finite volume on the boundary.
|
||||
void boundaryTypes(BoundaryTypes &BCtypes, const Vertex &vertex) const
|
||||
{
|
||||
const GlobalPosition &pos = vertex.geometry().center();
|
||||
if (pos[0] < eps_) // dirichlet conditions on left boundary
|
||||
BCtype.setAllDirichlet();
|
||||
if (pos[0] < eps_) // Dirichlet conditions on left boundary
|
||||
BCtypes.setAllDirichlet();
|
||||
else // neuman for the remaining boundaries
|
||||
BCtype.setAllNeumann();
|
||||
BCtypes.setAllNeumann();
|
||||
|
||||
}
|
||||
|
||||
// Evaluate the boundary conditions for a dirichlet boundary
|
||||
// segment. For this method, the 'values' parameter stores
|
||||
// Evaluate the Dirichlet boundary conditions for a finite volume
|
||||
// on the grid boundary. Here, the 'values' parameter stores
|
||||
// primary variables.
|
||||
void dirichlet(PrimaryVariables &values, const Vertex &vertex) const
|
||||
{
|
||||
@ -171,10 +151,9 @@ public:
|
||||
values[Indices::SnIdx] = 0.0; // 0 % oil saturation on left boundary
|
||||
}
|
||||
|
||||
// Evaluate the boundary conditions for a neumann boundary
|
||||
// segment. For this method, the 'values' parameter stores the
|
||||
// mass flux in normal direction of each phase. Negative values
|
||||
// mean influx.
|
||||
// Evaluate the boundary conditions for a Neumann boundary
|
||||
// segment. Here, the 'values' parameter stores the mass flux in
|
||||
// normal direction of each phase. Negative values mean influx.
|
||||
void neumann(PrimaryVariables &values,
|
||||
const Element &element,
|
||||
const FVElementGeometry &fvElemGeom,
|
||||
@ -186,12 +165,11 @@ public:
|
||||
fvElemGeom.boundaryFace[boundaryFaceIdx].ipGlobal;
|
||||
Scalar right = this->bboxMax()[0];
|
||||
if (pos[0] > right - eps_) {
|
||||
// oil outflux of 0.3 g/(m * s) on the right boundary of
|
||||
// the domain.
|
||||
// oil outflux of 0.3 g/(m * s) on the right boundary.
|
||||
values[Indices::contiWEqIdx] = 0;
|
||||
values[Indices::contiNEqIdx] = 3e-4;
|
||||
} else {
|
||||
// no-flow on the remaining neumann-boundaries
|
||||
// no-flow on the remaining Neumann-boundaries.
|
||||
values[Indices::contiWEqIdx] = 0;
|
||||
values[Indices::contiNEqIdx] = 0;
|
||||
}
|
||||
@ -209,10 +187,9 @@ public:
|
||||
}
|
||||
|
||||
// Evaluate the source term for all phases within a given
|
||||
// sub-control-volume. For this method, the \a values parameter
|
||||
// stores the rate mass generated or annihilate per volume
|
||||
// unit. Positive values mean that mass is created, negative ones
|
||||
// mean that it vanishes.
|
||||
// sub-control-volume. In this case, the 'values' parameter stores
|
||||
// the rate mass generated or annihilate per volume unit. Positive
|
||||
// values mean that mass is created.
|
||||
void source(PrimaryVariables &values,
|
||||
const Element &element,
|
||||
const FVElementGeometry &fvElemGeom,
|
||||
@ -223,6 +200,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
// small epsilon value
|
||||
static const Scalar eps_ = 3e-6;
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user