README.md 6.11 KB
Newer Older
1
2
3
4
5
6
7
8
9
<!--- Example picture --->
<p align="center">
    <img src="../../doc/img/example1_network.png" alt="frackit example 1" width="800"/>
</p>

Example 1
=========

In this exemplary application, a network of quadrilateral fractures is generated
Dennis Gläser's avatar
Dennis Gläser committed
10
within the unit cube (see image above). The main file containing the source code
11
to this example is the file `example1.cc` which is located in this folder. Note
Dennis Gläser's avatar
Dennis Gläser committed
12
that this description focuses on the C++ implementation, but in `example1.py`
13
it is illustrated how to realize this example using the Frackit python bindings.
Dennis Gläser's avatar
Dennis Gläser committed
14

15
16
Two main orientations are considered for the quadrilaterals, for both of which
a corresponding instance of the `QuadrilateralSampler` class is created.
Dennis Gläser's avatar
Dennis Gläser committed
17
For example, we instantiate an instance of this class by writing:
18
19

```cpp
Dennis Gläser's avatar
Dennis Gläser committed
20
21
22
static constexpr int worldDimension = 3;

using ctype = double;
Dennis Gläser's avatar
Dennis Gläser committed
23
24
using NormalDistro = std::normal_distribution<ctype>;
using UniformDistro = std::uniform_real_distribution<ctype>;
Dennis Gläser's avatar
Dennis Gläser committed
25
26
27
28
using QuadSampler = QuadrilateralSampler<worldDimension>;

Box<ctype> domain(0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
QuadSampler quadSampler(makeUniformPointSampler(domain),         // point sampler that samples the center points of the quadrilaterals
Dennis Gläser's avatar
Dennis Gläser committed
29
30
31
32
                        NormalDistro(toRadians(0.0), toRadians(5.0)),  // strike angle: mean value & standard deviation
                        NormalDistro(toRadians(0.0), toRadians(5.0)),  // dip angle: mean value & standard deviation
                        UniformDistro(0.4, 0.8),                       // strike length
                        UniformDistro(0.4, 0.8));                      // dip length
33
34
35
36
37
38
```

The first constructor argument is a point sampler with which the center points of
the quadrilaterals are sampled. Here we use uniformly sampled points in the unit
cube, which is represented by an instance of the `Box` class,  stored in the
variable `domain`. The second and third arguments define the distributions for
Dennis Gläser's avatar
Dennis Gläser committed
39
the strike and dip angle (for details see the [class documentation][2]), where in this case we use uniform distributions with
Dennis Gläser's avatar
Dennis Gläser committed
40
41
a mean value of 0° and a standard deviation of 5°. The fourth and last arguments
are distributions for the sizes of the quadrilaterals in strike and dip direction.
42

Dennis Gläser's avatar
Dennis Gläser committed
43
In the example, the quadrilaterals are sampled from the two samplers `quadSampler1` and
Dennis Gläser's avatar
Dennis Gläser committed
44
45
46
47
48
49
`quadSampler2`, using the `()` operator:

```cpp
auto quad = sampleIntoSet1 ? quadSampler1() : quadSampler2();
```

Dennis Gläser's avatar
Dennis Gläser committed
50
Here, we use the boolean variable `sampleIntoSet1` to determine from
Dennis Gläser's avatar
Dennis Gläser committed
51
52
which sampler we should sample the next quadrilateral (more details follow below).
The variable `quad` holds a new candidate for an entity of the network, however,
Dennis Gläser's avatar
Dennis Gläser committed
53
we want to enforce certain constraints such as a minimum distance between
Dennis Gläser's avatar
Dennis Gläser committed
54
55
56
entities. For this we use instances of the `EntityNetworkConstraints` class and
configure it as desired. For example, the constraints on entities of the same
orientation are defined in this example as follows:
57
58

```cpp
59
60
61
62
63
64
// We want to enforce some constraints on the set of quadrilaterals.
// In particular, for entities of the same set we want a minimum spacing
// distance of 5cm, and the quadrilaterals must not intersect in angles
// less than 30°. Moreover, if they intersect, we don't want intersection
// edges whose length is smaller than 5cm, and, the intersection should not
// be too close to the boundary of one of two intersecting quadrilaterals. Here: 5cm.
65
EntityNetworkConstraints<ctype> constraintsOnSelf;
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
constraintsOnSelf.setMinDistance(0.05);
constraintsOnSelf.setMinIntersectingAngle(toRadians(30.0));
constraintsOnSelf.setMinIntersectionMagnitude(0.05);
constraintsOnSelf.setMinIntersectionDistance(0.05);
```

In the main loop of quadrilateral generation, the fulfilment of these constraints is
evaluated against the other quadrilaterals with:

```cpp
auto& entitySet = sampleIntoSet1 ? entitySet1 : entitySet2;
if (!constraintsOnSelf.evaluate(entitySet, quad))
{ status.increaseRejectedCounter(); continue; }
```

where `entityset1` and `entitySet2` are of type `std::vector<Quadrilateral>` and
Dennis Gläser's avatar
Dennis Gläser committed
82
83
store all quadrilaterals that are accepted. The function `evaluate` of the
`EntityNetworkConstraints` class evaluates the constraints for `quad` against all
Dennis Gläser's avatar
Dennis Gläser committed
84
entities contained in `entitySet` and returns `true` only if no violation of
Dennis Gläser's avatar
Dennis Gläser committed
85
86
any of the defined constraints has been found. After an admissible quadrilateral
has been generated, the line
87
88
89
90
91
92
93
94
95

```cpp
// sample into the other set the next time
sampleIntoSet1 = !sampleIntoSet1;
```

at the end of the loop makes sure that a quadrilateral of the other orientation
is sampled next. In [Example 3][0] we will get to know how to use helper classes
that store different entity sets and automatically sample from various sampler
Dennis Gläser's avatar
Dennis Gläser committed
96
classes such that this can be written more easily.
97
98
99
100
101

After the desired number of entities has been generated, the entities are cast
into an entity network using the builder class:

```cpp
102
EntityNetworkBuilder<ctype> builder;
103
104
105
106
107
108
109
110
111
112
113
114
115
116
builder.addEntities(entitySet1);
builder.addEntities(entitySet2);

const auto network = builder.build();
```

This network can then be written to disk, for example in [Gmsh][1] (.geo) file format:

```cpp
GmshWriter writer(network);
writer.write("network", // filename of the .geo files (will add extension .geo automatically)
             0.1);      // element size to be used
```

Dennis Gläser's avatar
Dennis Gläser committed
117
118
119
120
121
122
123
124
125
Note that with the `EntityNetworkBuilder` class we have created a network that
solely carries information about the fracture entities. We have not defined any
domain in this example, the unit cube in the variable `domain` was only used to
sample the center points of the quadrilaterals. Thus, the geometry files written
by the `GmshWriter` also only contain data on the fracture entities. This can be
used in contexts where one is only interested in the fractures. In the following
examples we will see how to construct fracture networks embedded in one or more
(sub-)domains.

Dennis Gläser's avatar
Dennis Gläser committed
126
127
| [:arrow_right: Go to example 2](https://git.iws.uni-stuttgart.de/tools/frackit/tree/master/appl/example2) |
|---:|
128

Dennis Gläser's avatar
Dennis Gläser committed
129
[0]: https://git.iws.uni-stuttgart.de/tools/frackit/tree/master/appl/example3/README.md
130
[1]: http://gmsh.info/
Dennis Gläser's avatar
Dennis Gläser committed
131
[2]: https://git.iws.uni-stuttgart.de/tools/frackit/blob/master/frackit/sampling/quadrilateralsampler.hh