11.08., 9:00 - 11:00: Due to updates GitLab will be unavailable for some minutes between 09:00 and 11:00.

Commit bdf7df5a authored by Benedikt Kleinmeier's avatar Benedikt Kleinmeier

Merge branch 'master' into psychology

parents 21329876 9c467b36
Pipeline #272677 passed with stages
in 136 minutes and 16 seconds
......@@ -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");
}
......@@ -192,7 +192,7 @@ public class MeshQuantityPrinting {
bufferedWriterQualities2.write("iteration quality\n");
BufferedWriter bufferedWriterAngles = IOUtils.getWriter("angles_eik.csv", dir);
bufferedWriterAngles.write("iteration angle3D\n");
bufferedWriterAngles.write("iteration angle\n");
int init = 1;
while (!meshImprover.isInitialized()) {
......@@ -255,14 +255,14 @@ public class MeshQuantityPrinting {
bufferedWriterQualities2.write("iteration quality\n");
BufferedWriter bufferedWriterAngles = IOUtils.getWriter("angles_dist.csv", dir);
bufferedWriterAngles.write("iteration angle3D\n");
bufferedWriterAngles.write("iteration angle\n");
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)));
......
......@@ -321,7 +321,7 @@ public class IncrementalTriangulation<V extends IVertex, E extends IHalfEdge, F
// remove all faces outside the hole
VPolygon polygon = getMesh().toPolygon(hole);
Predicate<F> removePredicate = face -> !polygon.contains(getMesh().toTriangle(face).midPoint());
Predicate<F> removePredicate = face -> !polygon.contains(getMesh().toMidpoint(face));
cdt.getTriangulation().shrinkBorder(removePredicate, true);
IMesh<V, E, F> holeMesh = incrementalTriangulation.getMesh();
......
......@@ -545,6 +545,9 @@ public interface IMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
* @return (optional) a boundary edge
*/
default Optional<E> 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<V extends IVertex, E extends IHalfEdge, F extends IFace>
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<V extends IVertex, E extends IHalfEdge, F extends IFace>
}
default String toPythonValues(@NotNull final Function<V, Double> evalPoint) {
StringBuilder builder = new StringBuilder();
List<V> 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.
......
......@@ -116,7 +116,7 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
* @param vertex v
*/
default void adjustVertex(@NotNull final V vertex) {
getMesh().streamEdges(vertex).filter(edge -> 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<V extends IVertex, E extends IHalfEdge, F ext
* @param face they face which will be transformed into a hole
* @param mergeCondition the merge condition
* @param deleteIsoletedVertices if true isolated vertices, i.e. vertices without any edges, will be removed from the mesh
* @param vertexAdjust true means that boundary vertices will get their boundary edge as edge, false means there is no guarantee that this adjustment is made
* @return (optional) the hole or face itself it the face does not fulfill the merge condition
* or empty if due to the creation of the hole all faces will be removed!
*/
default Optional<F> createHole(@NotNull final F face, @NotNull final Predicate<F> mergeCondition, final boolean deleteIsoletedVertices) {
default Optional<F> createHole(@NotNull final F face, @NotNull final Predicate<F> 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<V extends IVertex, E extends IHalfEdge, F ext
}*/
}
default Optional<F> createHole(@NotNull final F face, @NotNull final Predicate<F> 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<V extends IVertex, E extends IHalfEdge, F ext
*
* @param removeCondition the remove condition
* @param deleteIsolatedVertices true then isolated vertices (they are not connected to an edge) will be removed.
* @param vertexAdjust true means that boundary vertices will get their boundary edge as edge, false means there is no guarantee that this adjustment is made
*/
default void shrinkBorder(final Predicate<F> removeCondition, final boolean deleteIsolatedVertices, final boolean vertexAdjust) {
shrinkBoundary(getMesh().getBorder(), removeCondition, deleteIsolatedVertices, vertexAdjust);
}
default void shrinkBorder(final Predicate<F> removeCondition, final boolean deleteIsolatedVertices) {
shrinkBoundary(getMesh().getBorder(), removeCondition, deleteIsolatedVertices);
shrinkBorder(removeCondition, deleteIsolatedVertices, true);
}
default void shrinkBoundary(final Predicate<F> removeCondition, final boolean deleteIsolatedVertices) {
......@@ -697,8 +707,9 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
*
* @param removeCondition the remove condition
* @param deleteIsolatedVertices true then isolated vertices (they are not connected to an edge) will be removed.
* @param adjustVertices true means that boundary vertices will get their boundary edge as edge, false means there is no guarantee that this adjustment is made
*/
default void shrinkBoundary(@NotNull final F boundary, final Predicate<F> removeCondition, final boolean deleteIsolatedVertices) {
default void shrinkBoundary(@NotNull final F boundary, final Predicate<F> removeCondition, final boolean deleteIsolatedVertices, final boolean adjustVertices) {
assert getMesh().isBoundary(boundary);
List<F> boundaryFaces = getMesh().getFaces(boundary);
......@@ -715,13 +726,17 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
nextNeighbouringFaces.add(face);
}
}
removeFaceAtBoundary(neighbouringFace, boundary, deleteIsolatedVertices);
removeFaceAtBoundary(neighbouringFace, boundary, deleteIsolatedVertices, adjustVertices);
}
}
neighbouringFaces = nextNeighbouringFaces;
} while (!neighbouringFaces.isEmpty());
}
default void shrinkBoundary(@NotNull final F boundary, final Predicate<F> removeCondition, final boolean deleteIsolatedVertices) {
shrinkBoundary(boundary, removeCondition, deleteIsolatedVertices, true);
}
default void removeFacesAtBoundary(@NotNull final Predicate<F> mergePredicate, @NotNull final Predicate<F> errorPredicate) throws IllegalMeshException {
mergeFaces(getMesh().getBorder(), mergePredicate, errorPredicate, true, 1);
for(F face : getMesh().getHoles()) {
......@@ -1215,8 +1230,9 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
* @param face the face that will be removed from the mesh
* @param boundary the boundary which has to be a neighbouring boundary of the face
* @param deleteIsolatedVertices true means that all vertices with degree smaller equals 1 will be removed as well
* @param adjustVertices true means that boundary vertices will get their boundary edge as edge, false means there is no guarantee that this adjustment is made
*/
default void removeFaceAtBoundary(@NotNull final F face, @NotNull final F boundary, final boolean deleteIsolatedVertices) {
default void removeFaceAtBoundary(@NotNull final F face, @NotNull final F boundary, final boolean deleteIsolatedVertices, final boolean adjustVertices) {
if(!getMesh().isDestroyed(face)) {
assert getMesh().streamFaces(face).filter(neighbour -> neighbour.equals(boundary)).count() > 0;
......@@ -1357,7 +1373,9 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
getMesh().destroyEdge(h1);
// adjust vertices such that we speed up the querry isBoundary(vertex).
vertices.stream().filter(getMesh()::isAlive).forEach(v -> adjustVertex(v));
if(adjustVertices) {
vertices.stream().filter(getMesh()::isAlive).forEach(v -> adjustVertex(v));
}
}
}
......@@ -1371,6 +1389,9 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
}
}
default void removeFaceAtBoundary(@NotNull final F face, @NotNull final F boundary, final boolean deleteIsolatedVertices) {
removeFaceAtBoundary(face, boundary, deleteIsolatedVertices, true);
}
/**
* Removes a face from the mesh by removing all boundary edges of the face.
......
......@@ -1953,7 +1953,7 @@ public interface ITriConnectivity<V extends IVertex, E extends IHalfEdge, F exte
* @return all visited faces in a first visited first in ordered queue, i.e. <tt>LinkedList</tt>.
*/
default LinkedList<E> straightWalk2DGatherDirectional(@NotNull final F face, @NotNull final VPoint direction, @NotNull final Predicate<E> additionalStopCondition) {
VPoint q = getMesh().toTriangle(face).midPoint();
VPoint q = getMesh().toMidpoint(face);
assert getMesh().toTriangle(face).contains(q);
Predicate<E> defaultStopCondion = e -> isRightOf(q.x, q.y, e);
......@@ -2734,7 +2734,8 @@ public interface ITriConnectivity<V extends IVertex, E extends IHalfEdge, F exte
* this might happen if the line intersects a point, in this case both neighbouring edges are feasible
*/
if(inEdge == null) {
inEdge = getMesh().streamEdges(startFace).filter(e -> isLeftOf(p.getX(), p.getY(), e)).findAny().get();
Optional<E> optEdge = getMesh().streamEdges(startFace).filter(e -> isLeftOf(p.getX(), p.getY(), e)).findAny();
inEdge = optEdge.get();
}
}
......
......@@ -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++;
......
......@@ -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.0;
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 = Integer.MAX_VALUE;
}
......@@ -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<V extends IVertex, E extends IHalfEdge, F extends IFace>
private static final String propVelocityY = "velocityY";
private static final String propAbsVelocity = "absVelocity";
private final IVertexContainerBoolean<V, E, F> fixpointC;
private final IEdgeContainerBoolean<V, E, F> constraintC;
private final IVertexContainerDouble<V, E, F> velocityXC;
private final IVertexContainerDouble<V, E, F> velocityYC;
private final IVertexContainerDouble<V, E, F> 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<V extends IVertex, E extends IHalfEdge, F extends IFace>
}
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<V extends IVertex, E extends IHalfEdge, F extends IFace>
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<V extends IVertex, E extends IHalfEdge, F extends IFace>
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<V extends IVertex, E extends IHalfEdge, F extends IFace>
deps = 0.0001 * initialEdgeLen;
computeFixPoints();
refiner.getConstrains().forEach(e -> setConstraint(e, true));
if(useSlidingLines) {
computeSlidingLines();
......@@ -549,7 +577,7 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
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)) {
......@@ -623,6 +651,9 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
// TODO: Get rid of VPoint
VPoint p1p2 = p1.subtract(p2);
double len = p1p2.distanceToOrigin();
if(len <= GeometryUtils.DOUBLE_EPS) {
return new VPoint(0, 0);
}
double desiredLen = 0.9 * Math.sqrt(3) * getDesiredEdgeLength(p1, p2);
double ratio = len / desiredLen;
double absForce = f.apply(ratio);
......@@ -765,6 +796,11 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
* @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 +846,7 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
*/
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 +890,9 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
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 +989,9 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
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 +1078,7 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
*/
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);
......@@ -1345,9 +1382,11 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
IPoint velocity = getForce(vertex);
double factor = 1.0;
IPoint movement = velocity.scalarMultiply(delta * factor);
while(!move(vertex, vertex.getX() + movement.getX(), vertex.getY() + movement.getY())) {
int count = 0;
while(!move(vertex, vertex.getX() + movement.getX(), vertex.getY() + movement.getY()) && count < 10) {
factor /= 2.0;
movement = velocity.scalarMultiply(delta * factor);
count++;
}
}
......@@ -1373,7 +1412,7 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
* This takes O(n) time where n is the number of removed faces which will be consumed.
*/
private void removeFacesAtBoundary() {
Predicate<F> isOutside = f -> distanceFunc.apply(getMesh().toTriangle(f).midPoint()) > 0;
Predicate<F> isOutside = f -> distanceFunc.apply(getMesh().toMidpoint(f)) > 0;
Predicate<F> isSeparated = f -> getMesh().isSeparated(f);
//Predicate<F> isInvalid = f -> !getTriangulation().isValid(f);
Predicate<F> isOfLowQuality = f -> faceToQuality(f) < Parameters.MIN_TRIANGLE_QUALITY && !isShortBoundaryEdge(f);
......@@ -1436,7 +1475,7 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
* <p>Shrinks the boundary such that there are no more triangles outside the boundary i.e. where the distance is positive.</p>
*/
private void shrinkBoundary() {
Predicate<F> removePredicate = face -> distanceFunc.apply(getTriangulation().getMesh().toTriangle(face).midPoint()) > 0;
Predicate<F> removePredicate = face -> distanceFunc.apply(getTriangulation().getMesh().toMidpoint(face)) > 0;
getTriangulation().shrinkBoundary(removePredicate, true);
}
......@@ -1445,7 +1484,7 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
* Note the border is part of the whole boundary which is defined by the border and the holes.</p>
*/
private void shrinkBorder() {
Predicate<F> removePredicate = face -> distanceFunc.apply(getTriangulation().getMesh().toTriangle(face).midPoint()) > 0;
Predicate<F> removePredicate = face -> distanceFunc.apply(getTriangulation().getMesh().toMidpoint(face)) > 0;
getTriangulation().shrinkBorder(removePredicate, true);
}
......@@ -1456,7 +1495,7 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
List<F> 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 +1581,41 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
}
}
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 +1624,21 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
}
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 +1646,17 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
}
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) {
......
......@@ -26,7 +26,7 @@ public interface IEikMeshImprover<V extends IVertex, E extends IHalfEdge, F exte
}
default Predicate<F> outsidePredicate(@NotNull final IDistanceFunction distanceFunc) {
return f -> distanceFunc.apply(getMesh().toTriangle(f).midPoint()) > 0;
return f -> distanceFunc.apply(getMesh().toMidpoint(f)) > 0;
}
default Predicate<F> lowQualityPredicate() {
......
......@@ -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);
}
}
......@@ -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;
......@@ -79,18 +80,21 @@ public class RunTimeCPU extends JFrame {
private static void stepAdaptiveRingEikMesh(double startLen, double endLen, double stepLen) {
IMeshSupplier<AVertex, AHalfEdge, AFace> 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<VShape> obstacles = new ArrayList<>();
double initialEdgeLength = startLen;
double minInitialEdgeLength = endLen;
List<Integer> nVertices = new ArrayList<>();
List<Double> qualities = new ArrayList<>();
List<Double> minQualities = new ArrayList<>();
List<Long> runTimes = new ArrayList<>();
List<Double> initlialEdgeLengths = new ArrayList<>();
while (initialEdgeLength >= minInitialEdgeLength) {
initlialEdgeLengths.add(initialEdgeLength);
final double currentEdgeLen = initialEdgeLength;
IEdgeLengthFunction adaptiveEdgeLength = p -> currentEdgeLen + Math.max(-distanceFunc.apply(p), 0) * 0.4;
GenEikMesh<AVertex, AHalfEdge, AFace> meshGenerator = new GenEikMesh<>(
distanceFunc,
adaptiveEdgeLength,
......@@ -98,6 +102,10 @@ public class RunTimeCPU extends JFrame {
bbox, obstacles,
supplier);
while (!meshGenerator.isInitialized()) {
meshGenerator.initialize();
}
StopWatch overAllTime = new StopWatch();
int steps = 0;
......@@ -119,14 +127,16 @@ public class RunTimeCPU extends JFrame {
log.info("step avg time: " + overAllTime.getTime() / steps + "[ms]");
nVertices.add(meshGenerator.getMesh().getVertices().size());
qualities.add(meshGenerator.getQuality());
minQualities.add(meshGenerator.getMinQuality());
runTimes.add( overAllTime.getTime());
/*PSMeshingPanel<MeshPoint, AVertex<MeshPoint>, AHalfEdge<MeshPoint>, AFace<MeshPoint>> distmeshPanel = new PSMeshingPanel(meshGenerator.getMesh(), f -> false, 1000, 800, bbox);
MeshPanel<AVertex, AHalfEdge, AFace> 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;
......@@ -137,23 +147,29 @@ public class RunTimeCPU extends JFrame {
System.out.println("#vertices: [" + nVertices.stream().map