From d46f4882129eb23d9ed9360fc3032f19adb43859 Mon Sep 17 00:00:00 2001
From: Benedikt Zoennchen
Date: Sat, 13 Jun 2020 20:36:37 +0200
Subject: [PATCH] small performance improvements of the EikMesh algorithm.
---
.../examples/MeshQuantityPrinting.java | 8 +-
.../mesh/gen/IncrementalTriangulation.java | 2 +-
.../org/vadere/meshing/mesh/inter/IMesh.java | 32 +++
.../meshing/mesh/inter/IPolyConnectivity.java | 37 +++-
.../meshing/mesh/inter/ITriConnectivity.java | 2 +-
.../improver/distmesh/Distmesh.java | 2 +-
.../improver/distmesh/Parameters.java | 5 +-
.../improver/eikmesh/gen/GenEikMesh.java | 95 ++++++---
.../eikmesh/gen/IEikMeshImprover.java | 2 +-
.../mesh/triangulation/plots/RunTimeCPU.java | 2 +-
.../plots/qualities/RunTimeCPU.java | 33 ++-
.../gen/GenRegularRefinement.java | 6 +-
.../GenUniformRefinementTriangulatorSFC.java | 20 +-
.../meshing/utils/math/GeometryUtilsMesh.java | 56 +++++
.../vadere/simulator/examples/Curvature.java | 27 ++-
.../calculators/mesh/AMeshEikonalSolver.java | 3 +-
.../mesh/MeshEikonalSolverFMMIterative.java | 16 +-
.../mesh/PredicateEdgeRefinement.java | 46 ++++
.../calculators/mesh/PredicateRefinement.java | 2 +
.../TimeCostFunctionFactory.java | 2 +-
...TimeCostGaussianPedestrianDensityMesh.java | 197 ++++++++++++++++++
.../TimeCostPedestrianDensityMesh.java | 48 ++---
.../projects/migration/GeometryCleaner.java | 4 +-
.../vadere/util/geometry/GeometryUtils.java | 18 +-
24 files changed, 555 insertions(+), 110 deletions(-)
create mode 100644 VadereSimulator/src/org/vadere/simulator/models/potential/solver/calculators/mesh/PredicateEdgeRefinement.java
create mode 100644 VadereSimulator/src/org/vadere/simulator/models/potential/timeCostFunction/TimeCostGaussianPedestrianDensityMesh.java
diff --git a/VadereMeshing/src/org/vadere/meshing/examples/MeshQuantityPrinting.java b/VadereMeshing/src/org/vadere/meshing/examples/MeshQuantityPrinting.java
index 7a6db671a..9081e764c 100644
--- a/VadereMeshing/src/org/vadere/meshing/examples/MeshQuantityPrinting.java
+++ b/VadereMeshing/src/org/vadere/meshing/examples/MeshQuantityPrinting.java
@@ -50,9 +50,9 @@ import java.util.stream.Collectors;
public class MeshQuantityPrinting {
public static void main(String... args) throws InterruptedException, IOException {
- spaceFillingCurve2();
+ //spaceFillingCurve2();
//uniformMeshDiscFunction(0.10);
- //uniformMeshDiscFunctionDistMesh(0.05);
+ uniformMeshDiscFunctionDistMesh(0.05);
//distMeshFail(0.05);
//delaunyTri("/poly/a.poly");
}
@@ -260,9 +260,9 @@ public class MeshQuantityPrinting {
int iteration = 1;
while (iteration < maxIteration+1) {
distmesh.improve();
- if(iteration + 1 == maxIteration+1) {
+ /*if(iteration + 1 == maxIteration+1) {
distmesh.reTriangulate(true);
- }
+ }*/
bufferedWriterIllegalEdges.write(iteration + " " + distmesh.getNumberOfIllegalTriangles() + "\n");
bufferedWriterQualities1.write(printQualities(iteration, distmesh, f -> GeometryUtils.qualityOf(f)));
bufferedWriterQualities2.write(printQualities(iteration, distmesh, f -> GeometryUtils.qualityLongestEdgeInCircle(f.p1, f.p2, f.p3)));
diff --git a/VadereMeshing/src/org/vadere/meshing/mesh/gen/IncrementalTriangulation.java b/VadereMeshing/src/org/vadere/meshing/mesh/gen/IncrementalTriangulation.java
index 47b9cd36d..31e0d9cda 100644
--- a/VadereMeshing/src/org/vadere/meshing/mesh/gen/IncrementalTriangulation.java
+++ b/VadereMeshing/src/org/vadere/meshing/mesh/gen/IncrementalTriangulation.java
@@ -321,7 +321,7 @@ public class IncrementalTriangulation removePredicate = face -> !polygon.contains(getMesh().toTriangle(face).midPoint());
+ Predicate removePredicate = face -> !polygon.contains(getMesh().toMidpoint(face));
cdt.getTriangulation().shrinkBorder(removePredicate, true);
IMesh holeMesh = incrementalTriangulation.getMesh();
diff --git a/VadereMeshing/src/org/vadere/meshing/mesh/inter/IMesh.java b/VadereMeshing/src/org/vadere/meshing/mesh/inter/IMesh.java
index a5e788b22..ccf10cdd9 100644
--- a/VadereMeshing/src/org/vadere/meshing/mesh/inter/IMesh.java
+++ b/VadereMeshing/src/org/vadere/meshing/mesh/inter/IMesh.java
@@ -545,6 +545,9 @@ public interface IMesh
* @return (optional) a boundary edge
*/
default Optional getBoundaryEdge(@NotNull final V vertex) {
+ if(isBoundary(getEdge(vertex))) {
+ return Optional.of(getEdge(vertex));
+ }
return streamEdges(vertex).filter(e -> isBoundary(e)).findAny();
}
@@ -1360,6 +1363,24 @@ public interface IMesh
return new VTriangle(new VPoint(vertices.get(0)), new VPoint(vertices.get(1)), new VPoint(vertices.get(2)));
}
+ default VPoint toMidpoint(@NotNull final F face) {
+ assert getVertices(face).size() == 3 : "number of vertices of " + face + " is " + getVertices(face).size();
+ E edge = getEdge(face);
+ V v1 = getVertex(edge);
+ V v2 = getVertex(getNext(edge));
+ V v3 = getVertex(getPrev(edge));
+ return GeometryUtils.getTriangleMidpoint(getX(v1), getY(v1), getX(v2), getY(v2), getX(v3), getY(v3));
+ }
+
+ default VPoint toCircumcenter(@NotNull final F face) {
+ assert getVertices(face).size() == 3 : "number of vertices of " + face + " is " + getVertices(face).size();
+ E edge = getEdge(face);
+ V v1 = getVertex(edge);
+ V v2 = getVertex(getNext(edge));
+ V v3 = getVertex(getPrev(edge));
+ return GeometryUtils.getCircumcenter(getX(v1), getY(v1), getX(v2), getY(v2), getX(v3), getY(v3));
+ }
+
/**
* Returns the midpoint {@link VPoint} of a triangle defined by the face.
* Assumption: The face represents a triangle, i.e. it has exactly 3 distinct points. This
@@ -2362,6 +2383,17 @@ public interface IMesh
}
+ default String toPythonValues(@NotNull final Function evalPoint) {
+ StringBuilder builder = new StringBuilder();
+ List vertices = getVertices();
+ for(V v : vertices) {
+ builder.append(evalPoint.apply(v) + ",");
+ }
+ builder.delete(builder.length()-1, builder.length());
+ builder.append("\n");
+ return builder.toString();
+ }
+
/**
* Constructs and returns a string which can be used to construct a matplotlib Triangulation
* which is helpful to plot the mesh.
diff --git a/VadereMeshing/src/org/vadere/meshing/mesh/inter/IPolyConnectivity.java b/VadereMeshing/src/org/vadere/meshing/mesh/inter/IPolyConnectivity.java
index 8ac4ec24f..3a129f164 100644
--- a/VadereMeshing/src/org/vadere/meshing/mesh/inter/IPolyConnectivity.java
+++ b/VadereMeshing/src/org/vadere/meshing/mesh/inter/IPolyConnectivity.java
@@ -116,7 +116,7 @@ public interface IPolyConnectivity isAtBoundary(edge)).findAny().ifPresent(edge -> getMesh().setEdge(vertex, edge));
+ getMesh().streamEdges(vertex).filter(edge -> getMesh().isBoundary(edge)).findAny().ifPresent(edge -> getMesh().setEdge(vertex, edge));
}
/**
@@ -632,14 +632,15 @@ public interface IPolyConnectivity createHole(@NotNull final F face, @NotNull final Predicate mergeCondition, final boolean deleteIsoletedVertices) {
+ default Optional createHole(@NotNull final F face, @NotNull final Predicate mergeCondition, final boolean deleteIsoletedVertices, final boolean vertexAdjust) {
if(mergeCondition.test(face)) {
getMesh().toHole(face);
- shrinkBoundary(face, mergeCondition, deleteIsoletedVertices);
+ shrinkBoundary(face, mergeCondition, deleteIsoletedVertices, vertexAdjust);
return Optional.of(face);
}
else {
@@ -665,6 +666,10 @@ public interface IPolyConnectivity createHole(@NotNull final F face, @NotNull final Predicate mergeCondition, final boolean deleteIsoletedVertices) {
+ return createHole(face, mergeCondition, deleteIsoletedVertices, true);
+ }
+
/**
* Shrinks the border as long as the removeCondition is satisfied i.e. a face will be removed if
* it is at the border (during the shrinking process) and satisfies the condition. Like a virus this
@@ -675,9 +680,14 @@ public interface IPolyConnectivity removeCondition, final boolean deleteIsolatedVertices, final boolean vertexAdjust) {
+ shrinkBoundary(getMesh().getBorder(), removeCondition, deleteIsolatedVertices, vertexAdjust);
+ }
+
default void shrinkBorder(final Predicate removeCondition, final boolean deleteIsolatedVertices) {
- shrinkBoundary(getMesh().getBorder(), removeCondition, deleteIsolatedVertices);
+ shrinkBorder(removeCondition, deleteIsolatedVertices, true);
}
default void shrinkBoundary(final Predicate removeCondition, final boolean deleteIsolatedVertices) {
@@ -697,8 +707,9 @@ public interface IPolyConnectivity removeCondition, final boolean deleteIsolatedVertices) {
+ default void shrinkBoundary(@NotNull final F boundary, final Predicate removeCondition, final boolean deleteIsolatedVertices, final boolean adjustVertices) {
assert getMesh().isBoundary(boundary);
List boundaryFaces = getMesh().getFaces(boundary);
@@ -715,13 +726,17 @@ public interface IPolyConnectivity removeCondition, final boolean deleteIsolatedVertices) {
+ shrinkBoundary(boundary, removeCondition, deleteIsolatedVertices, true);
+ }
+
default void removeFacesAtBoundary(@NotNull final Predicate mergePredicate, @NotNull final Predicate errorPredicate) throws IllegalMeshException {
mergeFaces(getMesh().getBorder(), mergePredicate, errorPredicate, true, 1);
for(F face : getMesh().getHoles()) {
@@ -1215,8 +1230,9 @@ public interface IPolyConnectivity neighbour.equals(boundary)).count() > 0;
@@ -1357,7 +1373,9 @@ public interface IPolyConnectivity adjustVertex(v));
+ if(adjustVertices) {
+ vertices.stream().filter(getMesh()::isAlive).forEach(v -> adjustVertex(v));
+ }
}
}
@@ -1371,6 +1389,9 @@ public interface IPolyConnectivityLinkedList.
*/
default LinkedList straightWalk2DGatherDirectional(@NotNull final F face, @NotNull final VPoint direction, @NotNull final Predicate additionalStopCondition) {
- VPoint q = getMesh().toTriangle(face).midPoint();
+ VPoint q = getMesh().toMidpoint(face);
assert getMesh().toTriangle(face).contains(q);
Predicate defaultStopCondion = e -> isRightOf(q.x, q.y, e);
diff --git a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/distmesh/Distmesh.java b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/distmesh/Distmesh.java
index aaba4d449..9c2014871 100644
--- a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/distmesh/Distmesh.java
+++ b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/distmesh/Distmesh.java
@@ -112,7 +112,7 @@ public class Distmesh {
}
public void reTriangulate(boolean force) {
- if(true || force || firstStep || maxMovementLen / initialEdgeLen > Parameters.TOL) {
+ if(force || firstStep || maxMovementLen / initialEdgeLen > Parameters.TOL) {
firstStep = false;
nTriangulations++;
diff --git a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/distmesh/Parameters.java b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/distmesh/Parameters.java
index c8fff387b..f4b46228e 100755
--- a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/distmesh/Parameters.java
+++ b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/distmesh/Parameters.java
@@ -17,7 +17,7 @@ public class Parameters {
public final static boolean uniform = false;
public final static String method = "Distmesh"; // "Distmesh" or "Density"
public final static double qualityMeasurement = 0.95;
- public final static double qualityConvergence = 0.001;
+ public final static double qualityConvergence = 0.01;
public final static double MINIMUM = 0.25;
public final static double DENSITYWEIGHT = 2;
public final static int NPOINTS = 100000;
@@ -25,5 +25,6 @@ public class Parameters {
public final static int SAMPLEDIVISION = 10;
public final static int SEGMENTDIVISION = 0;
//TODO increase this
- public final static int MAX_NUMBER_OF_STEPS = 100;
+ public final static int MAX_NUMBER_OF_STEPS = 200;
+ public final static int HIGHEST_LEGAL_TEST = 10;
}
diff --git a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/eikmesh/gen/GenEikMesh.java b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/eikmesh/gen/GenEikMesh.java
index 8d68eb138..cfbc6c0ab 100644
--- a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/eikmesh/gen/GenEikMesh.java
+++ b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/eikmesh/gen/GenEikMesh.java
@@ -3,12 +3,15 @@ package org.vadere.meshing.mesh.triangulation.improver.eikmesh.gen;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.vadere.meshing.mesh.IllegalMeshException;
+import org.vadere.meshing.mesh.inter.IEdgeContainerBoolean;
import org.vadere.meshing.mesh.inter.IFace;
import org.vadere.meshing.mesh.inter.IHalfEdge;
import org.vadere.meshing.mesh.inter.IMesh;
import org.vadere.meshing.mesh.inter.IMeshSupplier;
import org.vadere.meshing.mesh.inter.IIncrementalTriangulation;
import org.vadere.meshing.mesh.inter.IVertex;
+import org.vadere.meshing.mesh.inter.IVertexContainerBoolean;
+import org.vadere.meshing.mesh.inter.IVertexContainerDouble;
import org.vadere.meshing.mesh.iterators.EdgeIterator;
import org.vadere.meshing.mesh.iterators.EdgeIteratorReverse;
import org.vadere.meshing.mesh.triangulation.improver.IMeshImprover;
@@ -129,6 +132,12 @@ public class GenEikMesh
private static final String propVelocityY = "velocityY";
private static final String propAbsVelocity = "absVelocity";
+ private final IVertexContainerBoolean fixpointC;
+ private final IEdgeContainerBoolean constraintC;
+ private final IVertexContainerDouble velocityXC;
+ private final IVertexContainerDouble velocityYC;
+ private final IVertexContainerDouble absVelocityC;
+
/**
* Constructor to use EikMesh on an existing {@link org.vadere.meshing.mesh.inter.ITriangulation}, that is
* EikMesh uses this triangulation as a bases. It will refineSimplex2D the triangulation by using a longest edge
@@ -177,6 +186,12 @@ public class GenEikMesh
}
this.useSlidingLines = true;
this.smoothBorder = false;
+
+ this.fixpointC = triangulation.getMesh().getBooleanVertexContainer(propFixPoint);
+ this.constraintC = triangulation.getMesh().getBooleanEdgeContainer(propConstrained);
+ this.velocityXC = triangulation.getMesh().getDoubleVertexContainer(propVelocityX);
+ this.velocityYC = triangulation.getMesh().getDoubleVertexContainer(propVelocityY);
+ this.absVelocityC = triangulation.getMesh().getDoubleVertexContainer(propAbsVelocity);
}
/**
@@ -244,6 +259,12 @@ public class GenEikMesh
this.useSlidingLines = false;
this.smoothBorder = true;
+
+ this.fixpointC = triangulation.getMesh().getBooleanVertexContainer(propFixPoint);
+ this.constraintC = triangulation.getMesh().getBooleanEdgeContainer(propConstrained);
+ this.velocityXC = triangulation.getMesh().getDoubleVertexContainer(propVelocityX);
+ this.velocityYC = triangulation.getMesh().getDoubleVertexContainer(propVelocityY);
+ this.absVelocityC = triangulation.getMesh().getDoubleVertexContainer(propAbsVelocity);
}
/**
@@ -288,6 +309,12 @@ public class GenEikMesh
initialEdgeLen,
distanceFunc,
generateFixPoints());
+
+ this.fixpointC = refiner.getMesh().getBooleanVertexContainer(propFixPoint);
+ this.constraintC = refiner.getMesh().getBooleanEdgeContainer(propConstrained);
+ this.velocityXC = refiner.getMesh().getDoubleVertexContainer(propVelocityX);
+ this.velocityYC = refiner.getMesh().getDoubleVertexContainer(propVelocityY);
+ this.absVelocityC = refiner.getMesh().getDoubleVertexContainer(propAbsVelocity);
}
public GenEikMesh(
@@ -337,6 +364,7 @@ public class GenEikMesh
deps = 0.0001 * initialEdgeLen;
computeFixPoints();
+ refiner.getConstrains().forEach(e -> setConstraint(e, true));
if(useSlidingLines) {
computeSlidingLines();
@@ -549,7 +577,7 @@ public class GenEikMesh
private void computeForce(final V vertex) {
// TODO: Get rid of IPoint
IPoint p1 = getMesh().getPoint(vertex);
- boolean isAtBoundary = getMesh().isAtBoundary(vertex);
+ boolean isAtBoundary = isBoundary(vertex);
for(E edge : getMesh().getEdgeIt(vertex)) {
@@ -765,6 +793,11 @@ public class GenEikMesh
* @return true if the movement is legal, false otherwise
*/
private boolean isLegalMove(@NotNull final V vertex, double newX, double newY) {
+ // only test for early iterations!
+ if(nSteps > Parameters.HIGHEST_LEGAL_TEST) {
+ return true;
+ }
+
//if(vertex.distance(newX, newY) > GeometryUtils.DOUBLE_EPS) {
// TODO: at the boundary vertices can still overtake each other.
@@ -810,7 +843,7 @@ public class GenEikMesh
*/
private void updateFace(@NotNull F face) {
if(canBreak(face) && isBreaking(face)) {
- VPoint circumcenter = getMesh().toTriangle(face).getCircumcenter();
+ VPoint circumcenter = getMesh().toCircumcenter(face);
getTriangulation().splitTriangle(face, getMesh().createPoint(circumcenter.getX(), circumcenter.getY()), false);
}
}
@@ -854,9 +887,9 @@ public class GenEikMesh
newPosition = new VPoint(v1.getX(), v1.getY());
} else if(isFixPoint(v2)) {
newPosition = new VPoint(v2.getX(), v2.getY());
- } else if(getMesh().isAtBoundary(v1) || (isSlidePoint(v1) && !isSlidePoint(v2))) {
+ } else if(isBoundary(v1) || (isSlidePoint(v1) && !isSlidePoint(v2))) {
newPosition = new VPoint(v1.getX(), v1.getY());
- } else if(getMesh().isAtBoundary(v2) || (isSlidePoint(v2) && !isSlidePoint(v1))) {
+ } else if(isBoundary(v2) || (isSlidePoint(v2) && !isSlidePoint(v1))) {
newPosition = new VPoint(v2.getX(), v2.getY());
} else {
newPosition = new VPoint((v1.getX() + v2.getX()) * 0.5, (v1.getY() + v2.getY()) * 0.5);
@@ -953,8 +986,9 @@ public class GenEikMesh
if(faceToQuality(face) > 0.95) {
E edge = getMesh().getEdge(face);
if(edgeLengthFunc.apply(getMesh().toLine(edge).midPoint()) * 2.1 <= getMesh().toLine(edge).length()) {
- VPoint circumcenter = getMesh().toTriangle(face).getCircumcenter();
- return getMesh().toTriangle(face).contains(circumcenter);
+ VPoint circumcenter = getMesh().toCircumcenter(face);
+ return triangulation.contains(circumcenter.getX(), circumcenter.getY(), face);
+ //getMesh().toTriangle(face).contains(circumcenter);
}
}
return false;
@@ -1041,7 +1075,7 @@ public class GenEikMesh
*/
private VPoint computeProjection(@NotNull final V vertex) {
// we only project boundary vertices back
- if(getMesh().isAtBoundary(vertex)) {
+ if(isBoundary(vertex)) {
// TODO: get rid of VPoint
VPoint position = getMesh().toPoint(vertex);
@@ -1373,7 +1407,7 @@ public class GenEikMesh
* This takes O(n) time where n is the number of removed faces which will be consumed.
*/
private void removeFacesAtBoundary() {
- Predicate isOutside = f -> distanceFunc.apply(getMesh().toTriangle(f).midPoint()) > 0;
+ Predicate isOutside = f -> distanceFunc.apply(getMesh().toMidpoint(f)) > 0;
Predicate isSeparated = f -> getMesh().isSeparated(f);
//Predicate isInvalid = f -> !getTriangulation().isValid(f);
Predicate isOfLowQuality = f -> faceToQuality(f) < Parameters.MIN_TRIANGLE_QUALITY && !isShortBoundaryEdge(f);
@@ -1436,7 +1470,7 @@ public class GenEikMesh
* Shrinks the boundary such that there are no more triangles outside the boundary i.e. where the distance is positive.
*/
private void shrinkBoundary() {
- Predicate removePredicate = face -> distanceFunc.apply(getTriangulation().getMesh().toTriangle(face).midPoint()) > 0;
+ Predicate removePredicate = face -> distanceFunc.apply(getTriangulation().getMesh().toMidpoint(face)) > 0;
getTriangulation().shrinkBoundary(removePredicate, true);
}
@@ -1445,7 +1479,7 @@ public class GenEikMesh
* Note the border is part of the whole boundary which is defined by the border and the holes.
*/
private void shrinkBorder() {
- Predicate removePredicate = face -> distanceFunc.apply(getTriangulation().getMesh().toTriangle(face).midPoint()) > 0;
+ Predicate removePredicate = face -> distanceFunc.apply(getTriangulation().getMesh().toMidpoint(face)) > 0;
getTriangulation().shrinkBorder(removePredicate, true);
}
@@ -1456,7 +1490,7 @@ public class GenEikMesh
List faces = getTriangulation().getMesh().getFaces();
for(F face : faces) {
if(!getTriangulation().getMesh().isDestroyed(face) && !getTriangulation().getMesh().isHole(face)) {
- getTriangulation().createHole(face, f -> distanceFunc.apply(getTriangulation().getMesh().toTriangle(f).midPoint()) > 0, true);
+ getTriangulation().createHole(face, f -> distanceFunc.apply(getTriangulation().getMesh().toMidpoint(f)) > 0, true);
}
}
}
@@ -1542,38 +1576,41 @@ public class GenEikMesh
}
}
+ private boolean isBoundary(@NotNull final V vertex) {
+ return getMesh().isBoundary(getMesh().getEdge(vertex));
+ }
/*
* The following methods are helper methods to quickly access properties saved on vertices, edges and faces
*/
private void setConstraint(E edge, boolean constraint) {
- getMesh().setBooleanData(edge, propConstrained, constraint);
+ constraintC.setValue(edge, constraint);
}
private boolean isConstrained(E edge) {
- return getMesh().getBooleanData(edge, propConstrained);
+ return constraintC.getValue(edge);
}
private void setFixPoint(V vertex, boolean fixPoint) {
- getMesh().setBooleanData(vertex, propFixPoint, fixPoint);
+ fixpointC.setValue(vertex, fixPoint);
}
public boolean isFixPoint(V vertex) {
- return getMesh().getBooleanData(vertex, propFixPoint);
+ return fixpointC.getValue(vertex);
}
private void setVelocity(V vertex, IPoint velocity) {
- setVelocityX(vertex, velocity.getX());
- setVelocityY(vertex, velocity.getY());
+ velocityXC.setValue(vertex, velocity.getX());
+ velocityYC.setValue(vertex, velocity.getY());
}
private void setVelocityX(V vertex, double velX) {
- getMesh().setDoubleData(vertex, propVelocityX, velX);
+ velocityXC.setValue(vertex, velX);
}
private void setVelocityY(V vertex, double velY) {
- getMesh().setDoubleData(vertex, propVelocityY, velY);
+ velocityYC.setValue(vertex, velY);
}
private void increaseVelocity(V vertex, IPoint dvelocity) {
@@ -1582,21 +1619,21 @@ public class GenEikMesh
}
private double getVelocityX(V vertex) {
- return getMesh().getDoubleData(vertex, propVelocityX);
+ return velocityXC.getValue(vertex);
}
private void increaseVelocityX(V vertex, double dVelX) {
- double velX = getMesh().getDoubleData(vertex, propVelocityX);
- getMesh().setDoubleData(vertex, propVelocityX, velX + dVelX);
+ double velX = velocityXC.getValue(vertex);
+ velocityXC.setValue(vertex, velX + dVelX);
}
private void increaseVelocityY(V vertex, double dVelY) {
- double velY = getMesh().getDoubleData(vertex, propVelocityY);
- getMesh().setDoubleData(vertex, propVelocityY, velY + dVelY);
+ double velY = velocityYC.getValue(vertex);
+ velocityYC.setValue(vertex, velY + dVelY);
}
private double getVelocityY(V vertex) {
- return getMesh().getDoubleData(vertex, propVelocityY);
+ return velocityYC.getValue(vertex);
}
private VPoint getVelocity(V vertex) {
@@ -1604,17 +1641,17 @@ public class GenEikMesh
}
private void setAbsVelocity(V vertex, double absVelocity) {
- getMesh().setDoubleData(vertex, propAbsVelocity, absVelocity);
+ absVelocityC.setValue(vertex, absVelocity);
}
private void increaseAbsVelocity(V vertex, double dAbsVelocity) {
- double absVel = getMesh().getDoubleData(vertex, propAbsVelocity);
- getMesh().setDoubleData(vertex, propAbsVelocity, absVel + dAbsVelocity);
+ double absVel = absVelocityC.getValue(vertex);
+ absVelocityC.setValue(vertex, absVel + dAbsVelocity);
}
// setter to configure the algorithm strategy.
private double getAbsVelocity(V vertex) {
- return getMesh().getDoubleData(vertex, propAbsVelocity);
+ return absVelocityC.getValue(vertex);
}
public void setAllowEdgeSplits(final boolean allowEdgeSplits) {
diff --git a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/eikmesh/gen/IEikMeshImprover.java b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/eikmesh/gen/IEikMeshImprover.java
index 985a437f1..decfb111c 100644
--- a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/eikmesh/gen/IEikMeshImprover.java
+++ b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/improver/eikmesh/gen/IEikMeshImprover.java
@@ -26,7 +26,7 @@ public interface IEikMeshImprover outsidePredicate(@NotNull final IDistanceFunction distanceFunc) {
- return f -> distanceFunc.apply(getMesh().toTriangle(f).midPoint()) > 0;
+ return f -> distanceFunc.apply(getMesh().toMidpoint(f)) > 0;
}
default Predicate lowQualityPredicate() {
diff --git a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/plots/RunTimeCPU.java b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/plots/RunTimeCPU.java
index 32c46d27b..ac0c700fc 100644
--- a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/plots/RunTimeCPU.java
+++ b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/plots/RunTimeCPU.java
@@ -138,6 +138,6 @@ public class RunTimeCPU extends JFrame {
}
public static void main(String[] args) {
- stepUniformRing(0.05, 0.05, 0.05);
+ stepUniformRing(0.05, 0.05, 0.05);
}
}
diff --git a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/plots/qualities/RunTimeCPU.java b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/plots/qualities/RunTimeCPU.java
index 21a74cfc7..0936e35f6 100644
--- a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/plots/qualities/RunTimeCPU.java
+++ b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/plots/qualities/RunTimeCPU.java
@@ -7,6 +7,7 @@ import org.vadere.meshing.mesh.gen.AMesh;
import org.vadere.meshing.mesh.gen.AVertex;
import org.vadere.meshing.mesh.inter.IMeshSupplier;
import org.vadere.meshing.mesh.inter.IPointConstructor;
+import org.vadere.meshing.mesh.triangulation.improver.distmesh.DistmeshPanel;
import org.vadere.meshing.mesh.triangulation.improver.eikmesh.gen.GenEikMesh;
import org.vadere.meshing.mesh.gen.MeshPanel;
import org.vadere.meshing.mesh.triangulation.improver.eikmesh.EikMeshPoint;
@@ -29,6 +30,10 @@ public class RunTimeCPU extends JFrame {
private static final Logger log = Logger.getLogger(RunTimeCPU.class);
+ static {
+ log.setInfo();
+ }
+
/**
* Each geometry is contained this bounding box.
*/
@@ -79,7 +84,6 @@ public class RunTimeCPU extends JFrame {
private static void stepAdaptiveRingEikMesh(double startLen, double endLen, double stepLen) {
IMeshSupplier supplier = () -> new AMesh();
IDistanceFunction distanceFunc = p -> Math.abs(0.7 - Math.sqrt(p.getX() * p.getX() + p.getY() * p.getY())) - 0.3;
- IEdgeLengthFunction adaptiveEdgeLength = p -> 1.0 + Math.max(-distanceFunc.apply(p), 0) * 8.0;
List obstacles = new ArrayList<>();
double initialEdgeLength = startLen;
@@ -91,6 +95,8 @@ public class RunTimeCPU extends JFrame {
while (initialEdgeLength >= minInitialEdgeLength) {
initlialEdgeLengths.add(initialEdgeLength);
+ final double currentEdgeLen = initialEdgeLength;
+ IEdgeLengthFunction adaptiveEdgeLength = p -> currentEdgeLen + Math.max(-distanceFunc.apply(p), 0) * 0.4;
GenEikMesh meshGenerator = new GenEikMesh<>(
distanceFunc,
adaptiveEdgeLength,
@@ -98,6 +104,10 @@ public class RunTimeCPU extends JFrame {
bbox, obstacles,
supplier);
+ while (!meshGenerator.isInitialized()) {
+ meshGenerator.initialize();
+ }
+
StopWatch overAllTime = new StopWatch();
int steps = 0;
@@ -121,12 +131,12 @@ public class RunTimeCPU extends JFrame {
nVertices.add(meshGenerator.getMesh().getVertices().size());
runTimes.add( overAllTime.getTime());
- /*PSMeshingPanel, AHalfEdge, AFace> distmeshPanel = new PSMeshingPanel(meshGenerator.getMesh(), f -> false, 1000, 800, bbox);
+ MeshPanel distmeshPanel = new MeshPanel<>(meshGenerator.getMesh(),1000, 800);
JFrame frame = distmeshPanel.display();
frame.setVisible(true);
frame.setTitle("uniformRing()");
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
- distmeshPanel.repaint();*/
+ distmeshPanel.repaint();
initialEdgeLength = initialEdgeLength * 0.5;
@@ -142,7 +152,7 @@ public class RunTimeCPU extends JFrame {
private static void stepAdaptiveRingDistMesh(double startLen, double endLen, double stepLen) {
IMeshSupplier supplier = () -> new AMesh();
IDistanceFunction distanceFunc = p -> Math.abs(0.7 - Math.sqrt(p.getX() * p.getX() + p.getY() * p.getY())) - 0.3;
- IEdgeLengthFunction adaptiveEdgeLength = p -> 1.0 + Math.max(-distanceFunc.apply(p), 0) * 8.0;
+ //IEdgeLengthFunction adaptiveEdgeLength = p -> 1.0 + Math.max(-distanceFunc.apply(p), 0) * 0.4;
List obstacles = new ArrayList<>();
double initialEdgeLength = startLen;
@@ -154,6 +164,8 @@ public class RunTimeCPU extends JFrame {
while (initialEdgeLength >= minInitialEdgeLength) {
initlialEdgeLengths.add(initialEdgeLength);
+ final double currentEdgeLen = initialEdgeLength;
+ IEdgeLengthFunction adaptiveEdgeLength = p -> currentEdgeLen + Math.max(-distanceFunc.apply(p), 0) * 0.1;
Distmesh meshGenerator = new Distmesh(distanceFunc,
adaptiveEdgeLength,
initialEdgeLength,
@@ -169,24 +181,24 @@ public class RunTimeCPU extends JFrame {
meshGenerator.step();
overAllTime.suspend();
steps++;
- } while (!meshGenerator.hasMaximalSteps());
+ } while (steps <= 100);
log.info("#vertices: " + meshGenerator.getPoints().size());
log.info("quality: " + meshGenerator.getQuality());
log.info("#step: " + steps);
log.info("#tris: " + meshGenerator.getNumberOfReTriangulations());
log.info("overall time: " + overAllTime.getTime() + "[ms]");
- log.info("step avg time: " + overAllTime.getTime() / steps + "[ms]");
+ log.info("step avg time: " + overAllTime.getTime() / steps + "[ms]\n");
nVertices.add(meshGenerator.getPoints().size());
runTimes.add( overAllTime.getTime());
- /*PSDistmeshPanel distmeshPanel = new PSDistmeshPanel(meshGenerator, 1000, 800, bbox, t -> false);
+ DistmeshPanel distmeshPanel = new DistmeshPanel(meshGenerator, 1000, 800, bbox, t -> false);
JFrame frame = distmeshPanel.display();
frame.setVisible(true);
frame.setTitle("uniformRing()");
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
- distmeshPanel.repaint();*/
+ distmeshPanel.repaint();
initialEdgeLength = initialEdgeLength * 0.5;
@@ -200,7 +212,8 @@ public class RunTimeCPU extends JFrame {
}
public static void main(String[] args) {
- stepAdaptiveRingDistMesh(0.1, 0.005, 0.01);
- //stepAdaptiveRingEikMesh(0.1, 0.005, 0.01);
+ //stepAdaptiveRingDistMesh(0.1, 0.005, 0.01);
+ stepAdaptiveRingEikMesh(0.1, 0.005, 0.01);
+ //stepAdaptiveRingEikMesh(0.005, 0.005, 0.01);
}
}
diff --git a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/triangulator/gen/GenRegularRefinement.java b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/triangulator/gen/GenRegularRefinement.java
index b8d16905b..920ab1de2 100644
--- a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/triangulator/gen/GenRegularRefinement.java
+++ b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/triangulator/gen/GenRegularRefinement.java
@@ -96,10 +96,10 @@ public class GenRegularRefinement getLevel(e) == (maxLevel-1) && edgeRefinementPredicate.test(e);
//this.edgeAddToRefine = e -> getLevel(e) == (maxLevel-1) && edgeRefinementPredicate.test(e);
- VPoint p = new VPoint(5,5);
-
- this.edgeRefinementPredicate = e -> !getMesh().isBoundary(e) && getMesh().toTriangle(getMesh().getFace(e)).midPoint().distance(p) < 3.0 && (!isGreen(e) || getMesh().toLine(e).length() > 0.5);
+ //VPoint p = new VPoint(5,5);
+ //this.edgeRefinementPredicate = e -> !getMesh().isBoundary(e) && getMesh().toTriangle(getMesh().getFace(e)).midPoint().distance(p) < 3.0 && (!isGreen(e) || getMesh().toLine(e).length() > 0.5);
+ this.edgeRefinementPredicate = e -> getLevel(e) == (maxLevel-1) && (edgeRefinementPredicate.test(e));
this.finished = false;
this.coarse = false;
this.toRefine = new LinkedList<>();
diff --git a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/triangulator/gen/GenUniformRefinementTriangulatorSFC.java b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/triangulator/gen/GenUniformRefinementTriangulatorSFC.java
index 89e918a10..d4eb161a7 100644
--- a/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/triangulator/gen/GenUniformRefinementTriangulatorSFC.java
+++ b/VadereMeshing/src/org/vadere/meshing/mesh/triangulation/triangulator/gen/GenUniformRefinementTriangulatorSFC.java
@@ -527,6 +527,7 @@ public class GenUniformRefinementTriangulatorSFC sierpinksyFaceOrder = sfc.asList().stream().map(node -> getMesh().getFace(node.getEdge())).collect(Collectors.toList());
shrinkBorder();
createHoles();
+ adjustBoundaryVertexEdges();
//triangulation.smoothBorder();
sierpinksyFaceOrder.removeIf(face -> getMesh().isDestroyed(face) || getMesh().isHole(face));
@@ -617,8 +618,8 @@ public class GenUniformRefinementTriangulatorSFC
*/
private void shrinkBorder() {
- Predicate removePredicate = face -> distFunc.apply(triangulation.getMesh().toTriangle(face).midPoint()) > 0;
- triangulation.shrinkBorder(removePredicate, true);
+ Predicate removePredicate = face -> distFunc.apply(triangulation.getMesh().toMidpoint(face)) > 0;
+ triangulation.shrinkBorder(removePredicate, true, false);
}
@Override
@@ -652,6 +653,7 @@ public class GenUniformRefinementTriangulatorSFC cdt = new GenConstrainSplitter<>(getTriangulation(), lines, GeometryUtils.DOUBLE_EPS, sfc);
cdt.generate(false);
+ getTriangulation().setCanIllegalPredicate(e -> true);
projections.putAll(cdt.getProjections());
constrains.addAll(cdt.getConstrains());
@@ -661,9 +663,21 @@ public class GenUniformRefinementTriangulatorSFC faces = triangulation.getMesh().getFaces();
for(F face : faces) {
if(!triangulation.getMesh().isDestroyed(face) && !triangulation.getMesh().isHole(face)) {
- triangulation.createHole(face, f -> distFunc.apply(triangulation.getMesh().toTriangle(f).midPoint()) > 0, true);
+ triangulation.createHole(face, f -> distFunc.apply(triangulation.getMesh().toMidpoint(f)) > 0, true, false);
+ }
+ }
+ }
+
+ private void adjustBoundaryVertexEdges() {
+ for(F hole : getMesh().getHoles()) {
+ for(V v : getMesh().getVertexIt(hole)) {
+ triangulation.adjustVertex(v);
}
}
+
+ for(V v : getMesh().getVertexIt(getMesh().getBorder())) {
+ triangulation.adjustVertex(v);
+ }
}
/*private void createHoles() {
diff --git a/VadereMeshing/src/org/vadere/meshing/utils/math/GeometryUtilsMesh.java b/VadereMeshing/src/org/vadere/meshing/utils/math/GeometryUtilsMesh.java
index 4cdf4590c..ab1312ed8 100644
--- a/VadereMeshing/src/org/vadere/meshing/utils/math/GeometryUtilsMesh.java
+++ b/VadereMeshing/src/org/vadere/meshing/utils/math/GeometryUtilsMesh.java
@@ -106,6 +106,62 @@ public class GeometryUtilsMesh {
return new double[]{curvature, gaussianCurvature};
}
+ public static double[] curvature(@NotNull final IMesh mesh,
+ @NotNull final Function f,
+ @NotNull final Predicate valid,
+ @NotNull final E edge) {
+ double alpha = 0;
+ double beta = 0;
+ V v = mesh.getVertex(edge);
+ if(valid.test(v)) {
+ double vx = mesh.getX(v);
+ double vy = mesh.getY(v);
+ double vz = f.apply(v);
+
+ if(!mesh.isAtBoundary(edge)) {
+ V vi = mesh.getTwinVertex(edge);
+ V vj = mesh.getTwinVertex(mesh.getTwin(mesh.getNext(edge)));
+ V vk = mesh.getTwinVertex(mesh.getPrev(mesh.getTwin(edge)));
+
+ double vix = mesh.getX(vi);
+ double viy = mesh.getY(vi);
+ double viz = f.apply(vi);
+
+ double vjx = mesh.getX(vj);
+ double vjy = mesh.getY(vj);
+ double vjz = f.apply(vj);
+
+ if(valid.test(vi) && valid.test(vj) && valid.test(vk)) {
+ double eix = vix - vx;
+ double eiy = viy - vy;
+ double eiz = viz - vz;
+
+ double ejx = vjx - vx;
+ double ejy = vjy - vy;
+ double ejz = vjz - vz;
+
+ double ekx = mesh.getX(vk) - vx;
+ double eky = mesh.getY(vk) - vy;
+ double ekz = f.apply(vk) - vz;
+
+ alpha = GeometryUtils.angle3D(eix, eiy, eiz, ejx, ejy, ejz);
+ double[] ni = new double[]{ 0, 0, 0 };
+ double[] nk = new double[]{ 0, 0, 0 };
+
+ GeometryUtils.cross(new double[]{ eix, eiy, eiz}, new double[]{ ejx, ejy, ejz}, ni);
+ GeometryUtils.cross(new double[]{ ekx, eky, ekz }, new double[]{ eix, eiy, eiz}, nk);
+ GeometryUtils.norm3D(ni);
+ GeometryUtils.norm3D(nk);
+
+ double betai = GeometryUtils.angle3D(nk[0], nk[1], nk[2], ni[0], ni[1], ni[2]);
+ beta = Math.sqrt(eix * eix + eiy * eiy) * betai;
+ }
+ }
+ }
+
+ return new double[]{alpha, beta};
+ }
+
/*
public static double[] curvature(
@NotNull final IMesh mesh,
diff --git a/VadereSimulator/src/org/vadere/simulator/examples/Curvature.java b/VadereSimulator/src/org/vadere/simulator/examples/Curvature.java
index d6b2daa1c..968d77522 100644
--- a/VadereSimulator/src/org/vadere/simulator/examples/Curvature.java
+++ b/VadereSimulator/src/org/vadere/simulator/examples/Curvature.java
@@ -24,12 +24,15 @@ import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import java.util.function.Predicate;
public class Curvature {
public static void main(String ... args) throws IOException, InterruptedException {
- adaptoveEikonalSolver();
+ interativeEikonalSolver();
}
public static void interativeEikonalSolver() throws InterruptedException, IOException {
@@ -81,14 +84,24 @@ public class Curvature {
panel.repaint();
var tri = improver.getTriangulation();
- for(int i = 0; i < 8; i++) {
+ for(int i = 0; i < 4; i++) {
+
+ var curTri = tri;
+ List list = tri.getMesh().getBoundaryVertices();
+ Set initialVertices = new HashSet<>();
+ initialVertices.addAll(list);
+ list.stream().forEach(v -> curTri.getMesh().getAdjacentVertexIt(v).forEach(u -> initialVertices.add(u)));
+
+ Set initialVertices2 = new HashSet<>();
+ initialVertices.stream().forEach(v -> curTri.getMesh().getAdjacentVertexIt(v).forEach(u -> initialVertices2.add(u)));
+ initialVertices2.addAll(initialVertices);
var solver = new MeshEikonalSolverFMM<>(
p -> 1,
//Arrays.asList(new VPoint(5, 5)),
tri,
- tri.getMesh().getBoundaryVertices(),
- p -> -distanceFunction.apply(p));
+ initialVertices2,
+ p -> Math.abs(distanceFunction.apply(p)));
solver.solve();
System.out.println(solver.getPotential(5,5));
meshWriter.write(tri.getMesh().toPythonTriangulation(v -> solver.getPotential(v)));
@@ -107,7 +120,7 @@ public class Curvature {
}
System.out.println(maxCurvature);
- final double minEdgeLen = 0.025;
+ final double minEdgeLen = 0.1;
final var pTri = tri;
Predicate edgePredicate = e -> {
VLine line = pTri.getMesh().toLine(e);
@@ -121,7 +134,7 @@ public class Curvature {
pTri.getTriPoints(face, x, y, z, "curvature");
double totalArea = GeometryUtils.areaOfPolygon(x, y);
double curvature = InterpolationUtil.barycentricInterpolation(x, y, z, totalArea, p.getX(), p.getY());
- return len > minEdgeLen && curvature > 0.01;
+ return len > minEdgeLen && curvature > 0.25;
};
var triangulation = new IncrementalTriangulation<>(tri.getMesh().clone(), e -> true);
@@ -202,7 +215,7 @@ public class Curvature {
//Arrays.asList(new VPoint(5, 5)),
improver.getTriangulation(),
improver.getTriangulation().getMesh().getBoundaryVertices(),
- p -> -distanceFunction.apply(p));
+ p -> Math.abs(distanceFunction.apply(p)));
solver.solve();
meshWriter.write(solver.getTriangulation().getMesh().toPythonTriangulation(v -> solver.getPotential(v)));
meshWriter.close();
diff --git a/VadereSimulator/src/org/vadere/simulator/models/potential/solver/calculators/mesh/AMeshEikonalSolver.java b/VadereSimulator/src/org/vadere/simulator/models/potential/solver/calculators/mesh/AMeshEikonalSolver.java
index 7e0411d9f..f83d25769 100644
--- a/VadereSimulator/src/org/vadere/simulator/models/potential/solver/calculators/mesh/AMeshEikonalSolver.java
+++ b/VadereSimulator/src/org/vadere/simulator/models/potential/solver/calculators/mesh/AMeshEikonalSolver.java
@@ -228,7 +228,8 @@ public abstract class AMeshEikonalSolver refiner;
+ private @NotNull IDistanceFunction distFunc;
+
public MeshEikonalSolverFMMIterative(@NotNull final ITimeCostFunction timeCostFunction,
@NotNull final IIncrementalTriangulation triangulation,
@@ -53,6 +56,7 @@ public class MeshEikonalSolverFMMIterative(timeCostFunction, triangulation, targetVertices, distFunc));
+ this.distFunc = distFunc;
}
public MeshEikonalSolverFMMIterative(@NotNull final MeshEikonalSolverFMM solver) {
@@ -66,6 +70,8 @@ public class MeshEikonalSolverFMMIterative predicate = new PredicateRefinement<>(triangulation, clone, MIN_EDGE_LEN, MAX_CURVATURE);
+ //final Predicate predicate = new PredicateEdgeRefinement<>(solver, MIN_EDGE_LEN, MAX_CURVATURE);
+ //refiner = new GenRegularRefinement<>(triangulation, predicate, level);
refiner = new GenRegularRefinement<>(clone, predicate, level);
refiner.refine();
//refiner.coarse();
@@ -83,19 +89,25 @@ public class MeshEikonalSolverFMMIterative list = solver.getTriangulation().getMesh().getBoundaryVertices();
solver.solve();
+ System.out.println(solver.getTriangulation().getMesh().toPythonTriangulation(v -> solver.getPotential(v)));
level = 1;
double lastMaxCurvature = 0;
maxCurrentCurvature = Double.MAX_VALUE;
- while(maxCurrentCurvature > MAX_CURVATURE && !hasConverged(lastMaxCurvature, maxCurrentCurvature) && level < MAX_ITERATIONS) {
+ while (level < MAX_ITERATIONS) {
+ //while(maxCurrentCurvature > MAX_CURVATURE && !hasConverged(lastMaxCurvature, maxCurrentCurvature) && level < MAX_ITERATIONS) {
lastMaxCurvature = maxCurrentCurvature;
//System.out.println(solver.getTriangulation().getMesh().toPythonTriangulation(v -> solver.getPotential(v)));
maxCurrentCurvature = computeCurvature(solver.getTriangulation());
logger.debug("max curvature = " + maxCurrentCurvature);
+ solver.getTriangulation().removeTriEventListener(solver);
IIncrementalTriangulation refinedTriangulation = refine(solver.getTriangulation());
solver = new MeshEikonalSolverFMM<>(solver, refinedTriangulation, refinedTriangulation.getMesh().getBoundaryVertices());
solver.solve();
+
+ System.out.println(solver.getTriangulation().getMesh().toPythonTriangulation(v -> solver.getPotential(v)));
level++;
}
diff --git a/VadereSimulator/src/org/vadere/simulator/models/potential/solver/calculators/mesh/PredicateEdgeRefinement.java b/VadereSimulator/src/org/vadere/simulator/models/potential/solver/calculators/mesh/PredicateEdgeRefinement.java
new file mode 100644
index 000000000..14af5bb13
--- /dev/null
+++ b/VadereSimulator/src/org/vadere/simulator/models/potential/solver/calculators/mesh/PredicateEdgeRefinement.java
@@ -0,0 +1,46 @@
+package org.vadere.simulator.models.potential.solver.calculators.mesh;
+
+import org.jetbrains.annotations.NotNull;
+import org.vadere.meshing.mesh.inter.IFace;
+import org.vadere.meshing.mesh.inter.IHalfEdge;
+import org.vadere.meshing.mesh.inter.IVertex;
+import org.vadere.meshing.utils.math.GeometryUtilsMesh;
+import org.vadere.util.geometry.shapes.VLine;
+import java.util.function.Predicate;
+
+public class PredicateEdgeRefinement implements Predicate {
+ private final MeshEikonalSolverFMM solver;
+ private double minEdgeLen;
+ private double maxCurvature;
+
+ public PredicateEdgeRefinement(
+ @NotNull final MeshEikonalSolverFMM solver,
+ final double minEdgeLen,
+ final double maxCurvature
+ ){
+ this.solver = solver;
+ this.minEdgeLen = minEdgeLen;
+ this.maxCurvature = maxCurvature;
+ }
+
+ @Override
+ public boolean test(E e) {
+ V vertex = solver.getMesh().getVertex(e);
+ V vertexTwin = solver.getMesh().getTwinVertex(e);
+ VLine line = solver.getMesh().toLine(e);
+ double len = line.length();
+ double maxCurvature = 0.0;
+ if(solver.isBurned(solver.getMesh().getVertex(e)) && solver.isBurned(solver.getMesh().getTwinVertex(e))) {
+ for (E edge : solver.getMesh().getEdgeIt(vertex)) {
+ double[] curvatures = GeometryUtilsMesh.curvature(solver.getMesh(), v -> solver.getPotential(v), v -> solver.isBurned(v), edge);
+ maxCurvature = Math.max(maxCurvature, curvatures[1]);
+ }
+
+ for (E edge : solver.getMesh().getEdgeIt(vertexTwin)) {
+ double[] curvatures = GeometryUtilsMesh.curvature(solver.getMesh(), v -> solver.getPotential(v), v -> solver.isBurned(v), edge);
+ maxCurvature = Math.max(maxCurvature, curvatures[1]);
+ }
+ }
+ return len > minEdgeLen && maxCurvature > this.maxCurvature;
+ }
+}
diff --git a/VadereSimulator/src/org/vadere/simulator/models/potential/solver/calculators/mesh/PredicateRefinement.java b/VadereSimulator/src/org/vadere/simulator/models/potential/solver/calculators/mesh/PredicateRefinement.java
index 5b480cdcb..985797a60 100644
--- a/VadereSimulator/src/org/vadere/simulator/models/potential/solver/calculators/mesh/PredicateRefinement.java
+++ b/VadereSimulator/src/org/vadere/simulator/models/potential/solver/calculators/mesh/PredicateRefinement.java
@@ -5,6 +5,7 @@ import org.vadere.meshing.mesh.inter.IFace;
import org.vadere.meshing.mesh.inter.IHalfEdge;
import org.vadere.meshing.mesh.inter.IIncrementalTriangulation;
import org.vadere.meshing.mesh.inter.IVertex;
+import org.vadere.meshing.utils.math.GeometryUtilsMesh;
import org.vadere.util.geometry.GeometryUtils;
import org.vadere.util.geometry.shapes.VLine;
import org.vadere.util.geometry.shapes.VPoint;
@@ -33,6 +34,7 @@ public class PredicateRefinement -topography.distanceToObstacle(p)
);
- TimeCostPedestrianDensityMesh timeCostPedestrianDensityMesh = new TimeCostPedestrianDensityMesh<>(
+ TimeCostGaussianPedestrianDensityMesh timeCostPedestrianDensityMesh = new TimeCostGaussianPedestrianDensityMesh<>(
timeCostObstacleDensity,
triangulation,
loadingStrategy,
diff --git a/VadereSimulator/src/org/vadere/simulator/models/potential/timeCostFunction/TimeCostGaussianPedestrianDensityMesh.java b/VadereSimulator/src/org/vadere/simulator/models/potential/timeCostFunction/TimeCostGaussianPedestrianDensityMesh.java
new file mode 100644
index 000000000..6b53f3be2
--- /dev/null
+++ b/VadereSimulator/src/org/vadere/simulator/models/potential/timeCostFunction/TimeCostGaussianPedestrianDensityMesh.java
@@ -0,0 +1,197 @@
+package org.vadere.simulator.models.potential.timeCostFunction;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.vadere.meshing.mesh.inter.IFace;
+import org.vadere.meshing.mesh.inter.IHalfEdge;
+import org.vadere.meshing.mesh.inter.IIncrementalTriangulation;
+import org.vadere.meshing.mesh.inter.IVertex;
+import org.vadere.meshing.mesh.inter.IVertexContainerDouble;
+import org.vadere.meshing.mesh.triangulation.triangulator.gen.GenRegularRefinement;
+import org.vadere.meshing.utils.io.IOUtils;
+import org.vadere.meshing.utils.math.GeometryUtilsMesh;
+import org.vadere.simulator.models.potential.solver.timecost.ITimeCostFunctionMesh;
+import org.vadere.simulator.models.potential.timeCostFunction.loading.IPedestrianLoadingStrategy;
+import org.vadere.state.attributes.scenario.AttributesAgent;
+import org.vadere.state.scenario.Pedestrian;
+import org.vadere.state.scenario.Topography;
+import org.vadere.util.geometry.GeometryUtils;
+import org.vadere.util.geometry.shapes.IPoint;
+import org.vadere.util.geometry.shapes.VTriangle;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Predicate;
+
+/**
+ * A TimeCostFunction which reduces the travelling speed decreases with the obstacle density.
+ *
+ * @param
+ * @param
+ * @param
+ */
+public class TimeCostGaussianPedestrianDensityMesh implements ITimeCostFunctionMesh {
+
+ public static final String nameAgentDensity = "agent_density";
+
+ private final ITimeCostFunctionMesh timeCostFunction;
+ private final Topography topography;
+ private final IIncrementalTriangulation triangulation;
+ private final IVertexContainerDouble densities;
+ private final IPedestrianLoadingStrategy loadingStrategy;
+ private boolean updated;
+ private GenRegularRefinement refiner;
+
+ private final double R = 0.7;
+ private final int influenceRadius = 7;
+ private final double a;
+ private final double Sp;
+ private final double c;
+
+ // to debug
+ //private MeshPanel debugPanel;
+ private int step;
+ private BufferedWriter meshWriter;
+
+ public TimeCostGaussianPedestrianDensityMesh(
+ @NotNull final ITimeCostFunctionMesh timeCostFunction,
+ @NotNull final IIncrementalTriangulation triangulation,
+ @NotNull final IPedestrianLoadingStrategy loadingStrategy,
+ final AttributesAgent attributesAgent,
+ final Topography topography){
+ this.timeCostFunction = timeCostFunction;
+ this.loadingStrategy = loadingStrategy;
+ this.triangulation = triangulation;
+ this.topography = topography;
+ this.densities = triangulation.getMesh().getDoubleVertexContainer(nameAgentDensity);
+ this.updated = false;
+ this.refiner = new GenRegularRefinement<>(triangulation, e -> false);
+ this.refiner.setCoarsePredicate(v -> coarse(v));
+ this.refiner.setEdgeRefinementPredicate(e -> refine(e));
+ this.step = 0;
+ //TODO duplicated code
+ double dia = attributesAgent.getRadius() * 2.0;
+ Sp = (dia * dia * Math.sqrt(3)) * 0.5;
+ a = -1 / (2 * R * R);
+ c = 2 * Math.PI * R * R;
+ /*try {
+ this.meshWriter = IOUtils.getWriter("floorField_densities.txt", new File("/Users/bzoennchen/Development/workspaces/hmRepo/PersZoennchen/PhD/trash/generated/"));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }*/
+
+ //debugPanel = new MeshPanel<>(triangulation.getMesh(), 1000, 1000);
+ //debugPanel.display("debug");
+ }
+
+ private void refineMesh() {
+ long ms = System.currentTimeMillis();
+ refiner.coarse();
+ //debugPanel.paintImmediately(0, 0, debugPanel.getWidth(), debugPanel.getHeight());
+ refiner.refine();
+ long runTime = System.currentTimeMillis() - ms;
+ refiner.getMesh().garbageCollection();
+ //debugPanel.paintImmediately(0, 0, debugPanel.getWidth(), debugPanel.getHeight());
+ //System.out.println("runTime refinement = " + runTime);
+ }
+
+ private boolean coarse(@NotNull final V vertex) {
+ //return true;
+ for(Pedestrian pedestrian : topography.getPedestrianDynamicElements().getElements()) {
+ if(pedestrian.getPosition().distanceSq(triangulation.getMesh().toPoint(vertex)) > influenceRadius * influenceRadius) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean refine(@NotNull final E e) {
+ //return refiner.getLevel(e) < 2;
+ if(!triangulation.getMesh().isBoundary(e)) {
+ VTriangle triangle = triangulation.getMesh().toTriangle(triangulation.getMesh().getFace(e));
+ if(/*!refiner.isGreen(e) || */triangulation.getMesh().toLine(e).length() > 1.0) {
+ for(Pedestrian pedestrian : topography.getPedestrianDynamicElements().getElements()) {
+ if(pedestrian.getPosition().distanceSq(triangle.midPoint()) < influenceRadius * influenceRadius) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private double density(final double x1, final double y1, final double x2, final double y2, @Nullable final Pedestrian ped) {
+ double dist = GeometryUtils.lengthSq(x1 - x2, y1 - y2);
+ double density = loadingStrategy.calculateLoading(ped) * (Sp / (c)) * Math.exp(a * dist);
+ return density;
+ }
+
+ @Override
+ public double costAt(@NotNull final V v, @Nullable final Object caller) {
+ return timeCostFunction.costAt(v) + densities.getValue(v);
+ }
+
+ @Override
+ public double costAt(V v) {
+ return costAt(v, null);
+ }
+
+ @Override
+ public double costAt(@NotNull final IPoint p) {
+ F face = triangulation.locate(p).get();
+ double cost = 0;
+ if (!triangulation.getMesh().isBoundary(face)) {
+ cost = GeometryUtilsMesh.barycentricInterpolation(face, triangulation.getMesh(),
+ v -> densities.getValue(v), p.getX(), p.getY());
+ }
+ return timeCostFunction.costAt(p) + cost;
+ }
+
+ @Override
+ public boolean needsUpdate() {
+ return true;
+ }
+
+ @Override
+ public void update() {
+ timeCostFunction.update();
+ if(step % 10 == 0) {
+ //refineMesh();
+ }
+ step++;
+
+ //long ms = System.currentTimeMillis();
+
+
+ var mesh = triangulation.getMesh();
+ densities.reset();
+
+ for (Pedestrian element : topography.getPedestrianDynamicElements().getElements()) {
+ Optional optional = triangulation.locateFace(element.getPosition(), element);
+ assert optional.isPresent();
+
+ if (optional.isPresent()) {
+ F pedFace = optional.get();
+ Predicate predicate = v -> GeometryUtils.lengthSq(mesh.getX(v) - element.getPosition().x,
+ mesh.getY(v) - element.getPosition().y) < influenceRadius * influenceRadius;
+ Set closeVertices = triangulation.getVertices(element.getPosition().getX(), element.getPosition().getY(), pedFace, predicate);
+ for (V v : closeVertices) {
+ double density = densities.getValue(v) + density(element.getPosition().x, element.getPosition().y, mesh.getX(v), mesh.getY(v), element);
+ densities.setValue(v, density);
+ }
+ }
+ }
+
+ /*try {
+ this.meshWriter.write(triangulation.getMesh().toPythonTriangulation(v -> densities.getValue(v) + triangulation.getMesh().getDoubleData(v, TimeCostObstacleDensityMesh.nameObstacleDensity)));
+ this.meshWriter.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }*/
+ //long runTime = System.currentTimeMillis() - ms;
+ //System.out.println("runTime of density computation = " + runTime);
+ }
+}
diff --git a/VadereSimulator/src/org/vadere/simulator/models/potential/timeCostFunction/TimeCostPedestrianDensityMesh.java b/VadereSimulator/src/org/vadere/simulator/models/potential/timeCostFunction/TimeCostPedestrianDensityMesh.java
index 6040ad61c..962c681d9 100644
--- a/VadereSimulator/src/org/vadere/simulator/models/potential/timeCostFunction/TimeCostPedestrianDensityMesh.java
+++ b/VadereSimulator/src/org/vadere/simulator/models/potential/timeCostFunction/TimeCostPedestrianDensityMesh.java
@@ -2,18 +2,14 @@ package org.vadere.simulator.models.potential.timeCostFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.vadere.meshing.mesh.gen.MeshPanel;
-import org.vadere.meshing.mesh.gen.MeshRenderer;
-import org.vadere.meshing.mesh.gen.PVertex;
import org.vadere.meshing.mesh.inter.IFace;
import org.vadere.meshing.mesh.inter.IHalfEdge;
import org.vadere.meshing.mesh.inter.IIncrementalTriangulation;
import org.vadere.meshing.mesh.inter.IVertex;
import org.vadere.meshing.mesh.inter.IVertexContainerDouble;
import org.vadere.meshing.mesh.triangulation.triangulator.gen.GenRegularRefinement;
-import org.vadere.meshing.utils.color.Colors;
+import org.vadere.meshing.utils.io.IOUtils;
import org.vadere.meshing.utils.math.GeometryUtilsMesh;
-import org.vadere.simulator.models.potential.solver.timecost.ITimeCostFunction;
import org.vadere.simulator.models.potential.solver.timecost.ITimeCostFunctionMesh;
import org.vadere.simulator.models.potential.timeCostFunction.loading.IPedestrianLoadingStrategy;
import org.vadere.state.attributes.scenario.AttributesAgent;
@@ -23,7 +19,9 @@ import org.vadere.util.geometry.GeometryUtils;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VTriangle;
-import java.awt.*;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
@@ -37,7 +35,7 @@ import java.util.function.Predicate;
*/
public class TimeCostPedestrianDensityMesh implements ITimeCostFunctionMesh {
- public static final String nameObstacleDensity = "agent_density";
+ public static final String nameAgentDensity = "agent_density";
private final ITimeCostFunctionMesh timeCostFunction;
private final Topography topography;
@@ -47,15 +45,12 @@ public class TimeCostPedestrianDensityMesh refiner;
- private final double R = 0.7;
- private final int influenceRadius = 5;
- private final double a;
- private final double Sp;
- private final double c;
+ private final double influenceRadius = 7.0;
// to debug
//private MeshPanel debugPanel;
private int step;
+ private BufferedWriter meshWriter;
public TimeCostPedestrianDensityMesh(
@NotNull final ITimeCostFunctionMesh timeCostFunction,
@@ -67,17 +62,20 @@ public class TimeCostPedestrianDensityMesh(triangulation, e -> false);
this.refiner.setCoarsePredicate(v -> coarse(v));
this.refiner.setEdgeRefinementPredicate(e -> refine(e));
this.step = 0;
//TODO duplicated code
- double dia = attributesAgent.getRadius() * 2.0;
- Sp = (dia * dia * Math.sqrt(3)) * 0.5;
- a = -1 / (2 * R * R);
- c = 2 * Math.PI * R * R;
+
+ try {
+ this.meshWriter = IOUtils.getWriter("floorField_densities.txt", new File("/Users/bzoennchen/Development/workspaces/hmRepo/PersZoennchen/PhD/trash/generated/"));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
//debugPanel = new MeshPanel<>(triangulation.getMesh(), 1000, 1000);
//debugPanel.display("debug");
}
@@ -107,7 +105,7 @@ public class TimeCostPedestrianDensityMesh 5) {
+ if(/*!refiner.isGreen(e) || */triangulation.getMesh().toLine(e).length() > 1.0) {
for(Pedestrian pedestrian : topography.getPedestrianDynamicElements().getElements()) {
if(pedestrian.getPosition().distanceSq(triangle.midPoint()) < influenceRadius * influenceRadius) {
return true;
@@ -118,12 +116,6 @@ public class TimeCostPedestrianDensityMesh closeVertices = triangulation.getVertices(element.getPosition().getX(), element.getPosition().getY(), pedFace, predicate);
for (V v : closeVertices) {
- double density = densities.getValue(v) + density(element.getPosition().x, element.getPosition().y, mesh.getX(v), mesh.getY(v), element);
+ double density = densities.getValue(v) + loadingStrategy.calculateLoading(element) / (influenceRadius * influenceRadius * Math.PI);
densities.setValue(v, density);
}
}
}
+ try {
+ this.meshWriter.write(triangulation.getMesh().toPythonValues(v -> densities.getValue(v) + triangulation.getMesh().getDoubleData(v, TimeCostObstacleDensityMesh.nameObstacleDensity)));
+ this.meshWriter.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
//long runTime = System.currentTimeMillis() - ms;
//System.out.println("runTime of density computation = " + runTime);
}
diff --git a/VadereSimulator/src/org/vadere/simulator/projects/migration/GeometryCleaner.java b/VadereSimulator/src/org/vadere/simulator/projects/migration/GeometryCleaner.java
index 0492d5160..027d1cb3d 100644
--- a/VadereSimulator/src/org/vadere/simulator/projects/migration/GeometryCleaner.java
+++ b/VadereSimulator/src/org/vadere/simulator/projects/migration/GeometryCleaner.java
@@ -139,7 +139,7 @@ public class GeometryCleaner {
IDistanceFunction distanceFunction = IDistanceFunction.create(bound, polygons);
// 3. compute the segment-bounding simple polygon by using the distance function
- Predicate removePredicate = face -> distanceFunction.apply(triangulation.getMesh().toTriangle(face).midPoint()) > 0;
+ Predicate removePredicate = face -> distanceFunction.apply(triangulation.getMesh().toMidpoint(face)) > 0;
triangulation.shrinkBorder(removePredicate, true);
VPolygon boundingPolygon = GeometryUtils.toPolygon(triangulation.getMesh().getPoints(triangulation.getMesh().getBorder()));
@@ -147,7 +147,7 @@ public class GeometryCleaner {
List faces = triangulation.getMesh().getFaces();
for(PFace face : faces) {
if(!triangulation.getMesh().isBorder(face) && !triangulation.getMesh().isDestroyed(face) && !triangulation.getMesh().isHole(face)) {
- triangulation.createHole(face, f -> distanceFunction.apply(triangulation.getMesh().toTriangle(f).midPoint()) > 0, true);
+ triangulation.createHole(face, f -> distanceFunction.apply(triangulation.getMesh().toMidpoint(f)) > 0, true);
}
}
diff --git a/VadereUtils/src/org/vadere/util/geometry/GeometryUtils.java b/VadereUtils/src/org/vadere/util/geometry/GeometryUtils.java
index 116e745e6..a594ad7fb 100644
--- a/VadereUtils/src/org/vadere/util/geometry/GeometryUtils.java
+++ b/VadereUtils/src/org/vadere/util/geometry/GeometryUtils.java
@@ -226,16 +226,18 @@ public class GeometryUtils {
* @return the circumcenter of a triangle
*/
public static VPoint getCircumcenter(@NotNull final IPoint p1, @NotNull final IPoint p2, @NotNull final IPoint p3) {
-
assert !p1.equals(p2) && !p1.equals(p3) && !p2.equals(p3);
+ return getCircumcenter(p1.getX(), p1.getY(), p2.getX(), p2.getY(), p3.getX(), p3.getY());
+ }
- double d = 2 * (p1.getX() * (p2.getY() - p3.getY()) + p2.getX() * (p3.getY() - p1.getY()) + p3.getX() * (p1.getY() - p2.getY()));
- double x = ((p1.getX() * p1.getX() + p1.getY() * p1.getY()) * (p2.getY() - p3.getY())
- + (p2.getX() * p2.getX() + p2.getY() * p2.getY()) * (p3.getY() - p1.getY())
- + (p3.getX() * p3.getX() + p3.getY() * p3.getY()) * (p1.getY() - p2.getY())) / d;
- double y = ((p1.getX() * p1.getX() + p1.getY() * p1.getY()) * (p3.getX() - p2.getX())
- + (p2.getX() * p2.getX() + p2.getY() * p2.getY()) * (p1.getX() - p3.getX())
- + (p3.getX() * p3.getX() + p3.getY() * p3.getY()) * (p2.getX() - p1.getX())) / d;
+ public static VPoint getCircumcenter(final double x1, final double y1, final double x2, final double y2, final double x3, final double y3) {
+ double d = 2 * (x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2));
+ double x = ((x1 * x1 + y1 * y1) * (y2 - y3)
+ + (x2 * x2 + y2 * y2) * (y3 - y1)
+ + (x3 * x3 + y3 * y3) * (y1 - y2)) / d;
+ double y = ((x1 * x1 + y1 * y1) * (x3 - x2)
+ + (x2 * x2 + y2 * y2) * (x1 - x3)
+ + (x3 * x3 + y3 * y3) * (x2 - x1)) / d;
return new VPoint(x,y);
}
--
GitLab