Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
tools
frackit
Commits
2b31244a
Commit
2b31244a
authored
Dec 18, 2020
by
Dennis Gläser
Browse files
[ex3] modify example code
parent
1bb24325
Changes
3
Hide whitespace changes
Inline
Side-by-side
appl/example3/README.md
View file @
2b31244a
...
...
@@ -17,6 +17,8 @@ realize this example using the Frackit python bindings.__
*
use the
`MultiGeometrySampler`
and
`MultiGeometryEntitySet`
classes to conveniently compose a network out of multiple entity geometries
*
use the
`ConstraintsMatrix`
class to conveniently define several constraints to be fulfilled among different entity sets
*
define multiple confining/non-confining sub-domains to place the entities in
*
register the reasons for entity rejections within the
`Status`
class and print a summary
*
Build and write networks that are confined/unconfined to their embedding domains
### Read in a domain geometry
...
...
appl/example3/example3.cc
View file @
2b31244a
...
...
@@ -59,9 +59,9 @@ int main(int argc, char** argv)
// Compute its volume and get the boundary faces for constraint evaluation.
const
auto
&
networkDomain
=
solids
[
1
];
const
auto
domainVolume
=
computeMagnitude
(
networkDomain
);
const
auto
s
hell
s
=
OCCUtilities
::
getShells
(
networkDomain
);
if
(
s
hell
s
.
size
()
!=
1
)
throw
std
::
runtime_error
(
"Expected a single shell bounding the domain"
);
const
auto
domainBoundaryFaces
=
OCCUtilities
::
getFaces
(
s
hell
s
[
0
]);
const
auto
domainS
hell
=
OCCUtilities
::
getShells
(
networkDomain
);
if
(
domainS
hell
.
size
()
!=
1
)
throw
std
::
runtime_error
(
"Expected a single shell bounding the domain"
);
const
auto
domainBoundaryFaces
=
OCCUtilities
::
getFaces
(
domainS
hell
[
0
]);
...
...
@@ -157,14 +157,13 @@ int main(int argc, char** argv)
// of entity sets of different geometry types.
MultiGeometryEntitySet
<
Disk
,
Quad
>
entitySets
;
// Helper class for terminal output of the creation
// progress and definition of stop criterion etc
// Check if a value has been passed via the command line,
// otherwise use the defaults. This is used in the test suite
// to speed up testing time.
// Helper class for terminal output of the creation progress
// and definition of stop criterion etc. Check if a value has
// been passed via the command line, otherwise use the defaults.
// This is used in the test suite to speed up testing time.
SamplingStatus
status
;
status
.
setTargetCount
(
diskSetId
,
(
argc
>
1
?
std
::
stoi
(
argv
[
1
])
:
12
));
//
we want 11
entities of orientation 1
status
.
setTargetCount
(
quadSetId
,
(
argc
>
1
?
std
::
stoi
(
argv
[
1
])
:
16
));
//
we want 13
entities of orientation 2
status
.
setTargetCount
(
diskSetId
,
(
argc
>
1
?
std
::
stoi
(
argv
[
1
])
:
12
));
//
desired number of
entities of orientation 1
status
.
setTargetCount
(
quadSetId
,
(
argc
>
1
?
std
::
stoi
(
argv
[
1
])
:
16
));
//
desired number of
entities of orientation 2
// The actual network generation loop
ctype
containedNetworkArea
=
0.0
;
...
...
@@ -179,9 +178,9 @@ int main(int argc, char** argv)
if
(
status
.
finished
(
id
))
{
status
.
increaseRejectedCounter
(
"set finished"
);
continue
;
}
// Moreover, we want to avoid small fragments
(< 250 m²)
// Moreover, we want to avoid small fragments
const
auto
containedArea
=
computeContainedMagnitude
(
geom
,
networkDomain
);
if
(
containedArea
<
3
50.0
)
if
(
containedArea
<
2
50.0
)
{
status
.
increaseRejectedCounter
(
"minimum contained area violation"
);
continue
;
}
// enforce constraints w.r.t. to the other entities
...
...
appl/example3/example3.py
View file @
2b31244a
...
...
@@ -9,9 +9,8 @@ print("\n\n"
####################################################
# 1. Read in the domain geometry from .brep file. ##
# The file name is defined in CMakeLists.txt ##
####################################################
from
frackit.occutilities
import
readShape
,
getSolids
,
getShells
,
getFaces
,
getBoundingBox
from
frackit.occutilities
import
readShape
,
getSolids
,
getShells
,
getFaces
domainShape
=
readShape
(
"layers.brep"
)
# obtain the three solids contained in the file
...
...
@@ -22,12 +21,10 @@ if len(solids) != 3: sys.exit("Expected the .brep file to contain 3 solids")
# Compute its volume and get the boundary faces for constraint evaluation.
from
frackit.geometry
import
computeMagnitude
networkDomain
=
solids
[
1
]
domainVolume
=
computeMagnitude
(
networkDomain
);
shells
=
getShells
(
networkDomain
)
if
len
(
shells
)
!=
1
:
sys
.
exit
(
"Expected a single shell bounding the domain"
)
domainBoundaryFaces
=
getFaces
(
shells
[
0
])
if
len
(
domainBoundaryFaces
)
!=
6
:
sys
.
exit
(
"Expected 6 faces to bound the domain"
)
domainVolume
=
computeMagnitude
(
networkDomain
)
domainShell
=
getShells
(
networkDomain
)
if
len
(
domainShell
)
!=
1
:
sys
.
exit
(
"Expected a single shell bounding the domain"
)
domainBoundaryFaces
=
getFaces
(
domainShell
[
0
])
##############################################################################
...
...
@@ -36,9 +33,8 @@ if len(domainBoundaryFaces) != 6: sys.exit("Expected 6 faces to bound the domain
##############################################################################
# Bounding box of the domain in which we want to place the entities
# In order for this to work we parse the solid back into a wrapper around a BRep shape
from
frackit.geometry
import
Box
,
OCCShapeWrapper
domainBBox
=
getBoundingBox
(
OCCShapeWrapper
(
networkDomain
)
)
from
frackit.geometry
import
OCCShapeWrapper
,
getBoundingBox
domainBBox
=
getBoundingBox
(
networkDomain
)
# creates a uniform sampler within an interval
import
random
...
...
@@ -51,22 +47,24 @@ def normalSampler(mean, stdDev):
def
sample
():
return
random
.
gauss
(
mean
,
stdDev
)
return
sample
from
frackit.common
import
toRadians
,
Id
import
math
from
frackit.common
import
Id
from
frackit.sampling
import
DiskSampler
,
QuadrilateralSampler
,
makeUniformPointSampler
# sampler for disks (orientation 1)
diskSampler
=
DiskSampler
(
makeUniformPointSampler
(
domainBBox
),
# sampler for disk center points
uniformSampler
(
30.0
,
6.5
),
# major axis length: mean value & standard deviation
uniformSampler
(
24.0
,
4.5
),
# minor axis length: mean value & standard deviation
normalSampler
(
toR
adians
(
0.0
),
toR
adians
(
7.5
)),
# rotation around x-axis: mean value & standard deviation
normalSampler
(
toR
adians
(
0.0
),
toR
adians
(
7.5
)),
# rotation around y-axis: mean value & standard deviation
normalSampler
(
toR
adians
(
0.0
),
toR
adians
(
7.5
)))
# rotation around z-axis: mean value & standard deviation
diskSampler
=
DiskSampler
(
pointSampler
=
makeUniformPointSampler
(
domainBBox
),
majAxisSampler
=
uniformSampler
(
30.0
,
6.5
),
minAxisSampler
=
uniformSampler
(
24.0
,
4.5
),
xAngleSampler
=
normalSampler
(
math
.
r
adians
(
0.0
),
math
.
r
adians
(
7.5
)),
yAngleSampler
=
normalSampler
(
math
.
r
adians
(
0.0
),
math
.
r
adians
(
7.5
)),
zAngleSampler
=
normalSampler
(
math
.
r
adians
(
0.0
),
math
.
r
adians
(
7.5
)))
# sampler for quadrilaterals (orientation 2)
quadSampler
=
QuadrilateralSampler
(
makeUniformPointSampler
(
domainBBox
),
# sampler for quadrilateral center points
normalSampler
(
toR
adians
(
45.0
),
toR
adians
(
5.0
)),
# strike angle: mean value & standard deviation
normalSampler
(
toR
adians
(
90.0
),
toR
adians
(
5.0
)),
# dip angle: mean value & standard deviation
uniformSampler
(
30.0
,
60.0
),
# strike length
uniformSampler
(
30.0
,
60.0
))
# dip length
quadSampler
=
QuadrilateralSampler
(
pointSampler
=
makeUniformPointSampler
(
domainBBox
),
strikeAngleSampler
=
normalSampler
(
math
.
r
adians
(
45.0
),
math
.
r
adians
(
5.0
)),
dipAngleSampler
=
normalSampler
(
math
.
r
adians
(
90.0
),
math
.
r
adians
(
5.0
)),
strikeLengthSampler
=
uniformSampler
(
30.0
,
60.0
),
dipLengthSampler
=
uniformSampler
(
30.0
,
60.0
))
# Define ids for the two entity sets
diskSetId
=
Id
(
1
)
# we give the set of orientation one, consisting of disks, the id 1
...
...
@@ -84,7 +82,7 @@ from frackit.entitynetwork import EntityNetworkConstraints, EntityNetworkConstra
def
makeDefaultConstraints
():
c
=
EntityNetworkConstraints
()
c
.
setMinDistance
(
2.5
)
c
.
setMinIntersectingAngle
(
toR
adians
(
25.0
))
c
.
setMinIntersectingAngle
(
math
.
r
adians
(
25.0
))
c
.
setMinIntersectionMagnitude
(
5.0
)
c
.
setMinIntersectionDistance
(
2.5
)
return
c
...
...
@@ -100,7 +98,7 @@ constraints2.setMinDistance(5.0)
# Define constraints between entities of different sets
constraintsOnOther
=
makeDefaultConstraints
()
constraintsOnOther
.
setMinDistance
(
2.5
)
constraintsOnOther
.
setMinIntersectingAngle
(
toR
adians
(
40.0
))
constraintsOnOther
.
setMinIntersectingAngle
(
math
.
r
adians
(
40.0
))
# We can use the constraints matrix to facilitate constraint evaluation
constraintsMatrix
=
EntityNetworkConstraintsMatrix
()
...
...
@@ -116,7 +114,7 @@ constraintsMatrix.addConstraints(constraintsOnOther, # constraint instance
# Moreover, we define constraints w.r.t. the domain boundary
constraintsOnDomain
=
makeDefaultConstraints
()
constraintsOnDomain
.
setMinIntersectingAngle
(
toR
adians
(
15.0
))
constraintsOnDomain
.
setMinIntersectingAngle
(
math
.
r
adians
(
15.0
))
###########################
...
...
@@ -127,15 +125,15 @@ constraintsOnDomain.setMinIntersectingAngle(toRadians(15.0))
# progress and definition of stop criterion etc
from
frackit.sampling
import
SamplingStatus
status
=
SamplingStatus
()
status
.
setTargetCount
(
diskSetId
,
12
)
#
we want 11
entities of orientation 1
status
.
setTargetCount
(
quadSetId
,
16
)
#
we want 13
entities of orientation 2
status
.
setTargetCount
(
diskSetId
,
12
)
#
number of desired
entities of orientation 1
status
.
setTargetCount
(
quadSetId
,
16
)
#
number of desired
entities of orientation 2
# store all entity sets in a dictionary
entitySets
=
{
diskSetId
:
[],
quadSetId
:
[]}
# Alternate between set 1 & set 2 during sampling phase
sampleIntoSet1
=
True
containedNetworkArea
=
0.0
;
containedNetworkArea
=
0.0
while
not
status
.
finished
():
id
=
diskSetId
if
sampleIntoSet1
else
quadSetId
geom
=
diskSampler
()
if
sampleIntoSet1
else
quadSampler
()
...
...
@@ -146,10 +144,10 @@ while not status.finished():
status
.
increaseRejectedCounter
(
"set finished"
)
continue
# Moreover, we want to avoid small fragments
(< 250 m²)
# Moreover, we want to avoid small fragments
from
frackit.geometry
import
computeContainedMagnitude
containedArea
=
computeContainedMagnitude
(
geom
,
networkDomain
)
;
if
containedArea
<
3
50.0
:
containedArea
=
computeContainedMagnitude
(
geom
,
networkDomain
)
if
containedArea
<
2
50.0
:
status
.
increaseRejectedCounter
(
"minimum contained area violation"
)
continue
...
...
@@ -171,17 +169,17 @@ while not status.finished():
status
.
print
()
# keep track of entity area
containedNetworkArea
+=
containedArea
;
containedNetworkArea
+=
containedArea
# sample from the other set next time
sampleIntoSet1
=
not
sampleIntoSet1
# print the final entity density
density
=
containedNetworkArea
/
domainVolume
;
density
=
containedNetworkArea
/
domainVolume
print
(
"
\n
Entity density of the contained network: {:f} m²/m³
\n
"
.
format
(
density
))
# print info on rejection events
status
.
printRejectionData
()
;
status
.
printRejectionData
()
print
(
""
)
##########################################################################
...
...
@@ -192,19 +190,19 @@ print("")
# construct and write a contained network, i.e. write out both network and domain.
print
(
"Building and writing contained, confined network"
)
from
frackit.entitynetwork
import
EntityNetworkBuilder
,
ContainedEntityNetworkBuilder
builder
=
ContainedEntityNetworkBuilder
()
;
builder
=
ContainedEntityNetworkBuilder
()
# add sub-domains
builder
.
addConfiningSubDomain
(
solids
[
0
],
Id
(
1
))
;
builder
.
addConfiningSubDomain
(
networkDomain
,
Id
(
2
))
;
builder
.
addConfiningSubDomain
(
solids
[
2
],
Id
(
3
))
;
builder
.
addConfiningSubDomain
(
solids
[
0
],
Id
(
1
))
builder
.
addConfiningSubDomain
(
networkDomain
,
Id
(
2
))
builder
.
addConfiningSubDomain
(
solids
[
2
],
Id
(
3
))
# The entites that we created all belong to subdomain 2
for
setId
in
entitySets
:
builder
.
addSubDomainEntities
(
entitySets
[
setId
],
Id
(
2
))
# now we can build and write out the network in Gmsh file format
from
frackit.io
import
GmshWriter
gmshWriter
=
GmshWriter
(
builder
.
build
())
;
gmshWriter
=
GmshWriter
(
builder
.
build
())
gmshWriter
.
setMeshSize
(
GmshWriter
.
GeometryTag
.
entity
,
2.5
)
gmshWriter
.
setMeshSize
(
GmshWriter
.
GeometryTag
.
subDomain
,
5.0
)
gmshWriter
.
write
(
"contained_confined"
)
# body of the filename to be used (will add .geo)
...
...
@@ -212,33 +210,33 @@ gmshWriter.write("contained_confined") # body of the filename to be used (will a
# we can also not confine the network to its sub-domain,
# simply by adding the sub-domains as non-confining
print
(
"Building and writing contained, unconfined network"
)
builder
.
clear
()
;
builder
.
addSubDomain
(
solids
[
0
],
Id
(
1
))
;
builder
.
addSubDomain
(
networkDomain
,
Id
(
2
))
;
builder
.
addSubDomain
(
solids
[
2
],
Id
(
3
))
;
builder
.
clear
()
builder
.
addSubDomain
(
solids
[
0
],
Id
(
1
))
builder
.
addSubDomain
(
networkDomain
,
Id
(
2
))
builder
.
addSubDomain
(
solids
[
2
],
Id
(
3
))
for
setId
in
entitySets
:
builder
.
addSubDomainEntities
(
entitySets
[
setId
],
Id
(
2
))
gmshWriter
=
GmshWriter
(
builder
.
build
())
;
gmshWriter
=
GmshWriter
(
builder
.
build
())
gmshWriter
.
setMeshSize
(
GmshWriter
.
GeometryTag
.
entity
,
2.5
)
gmshWriter
.
setMeshSize
(
GmshWriter
.
GeometryTag
.
subDomain
,
5.0
)
gmshWriter
.
write
(
"contained_unconfined"
)
;
gmshWriter
.
write
(
"contained_unconfined"
)
# We could also only write out the network, without the domain
# For example, confining the network to the sub-domain...
print
(
"Building and writing uncontained, confined network"
)
uncontainedBuilder
=
EntityNetworkBuilder
()
uncontainedBuilder
.
addConfiningSubDomain
(
networkDomain
,
Id
(
2
))
;
uncontainedBuilder
.
addConfiningSubDomain
(
networkDomain
,
Id
(
2
))
for
setId
in
entitySets
:
uncontainedBuilder
.
addSubDomainEntities
(
entitySets
[
setId
],
Id
(
2
))
gmshWriter
=
GmshWriter
(
uncontainedBuilder
.
build
())
;
gmshWriter
=
GmshWriter
(
uncontainedBuilder
.
build
())
gmshWriter
.
setMeshSize
(
GmshWriter
.
GeometryTag
.
entity
,
2.5
)
gmshWriter
.
write
(
"uncontained_confined"
)
;
gmshWriter
.
write
(
"uncontained_confined"
)
# ... or not confining it
print
(
"Building and writing uncontained, unconfined network"
)
uncontainedBuilder
.
clear
()
;
uncontainedBuilder
.
clear
()
for
setId
in
entitySets
:
uncontainedBuilder
.
addSubDomainEntities
(
entitySets
[
setId
],
Id
(
2
))
gmshWriter
=
GmshWriter
(
uncontainedBuilder
.
build
())
;
gmshWriter
=
GmshWriter
(
uncontainedBuilder
.
build
())
gmshWriter
.
setMeshSize
(
GmshWriter
.
GeometryTag
.
entity
,
2.5
)
gmshWriter
.
write
(
"uncontained_unconfined"
)
;
gmshWriter
.
write
(
"uncontained_unconfined"
)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment