Commit 1d6c7133 authored by BZoennchen's avatar BZoennchen

finish new property data structure supported by fastutil.

parent 7ac00df9
package org.vadere.meshing.mesh.gen;
import it.unimi.dsi.fastutil.booleans.BooleanArrayList;
import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
......@@ -38,12 +39,17 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
private AFace boundary;
private List<AHalfEdge> edges;
private List<AVertex> vertices;
//TODO: test the new property structure!
private Map<String, AObjectArrayList<?>> verticesData;
private Map<String, AObjectArrayList<?>> halfEdgesData;
private Map<String, AObjectArrayList<?>> facesData;
private Map<String, DoubleArrayList> verticesDoubleData;
private Map<String, DoubleArrayList> facesDoubleData;
private Map<String, DoubleArrayList> halfEdgesDoubleData;
private Map<String, BooleanArrayList> verticesBooleanData;
private Map<String, BooleanArrayList> facesBooleanData;
private Map<String, BooleanArrayList> halfEdgesBooleanData;
public AMesh() {
clear();
......@@ -61,12 +67,18 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
this.numberOfEdges = 0;
this.numberOfVertices = 0;
this.numberOfHoles = 0;
this.verticesData = new HashMap<>();
this.halfEdgesData = new HashMap<>();
this.facesData = new HashMap<>();
this.verticesDoubleData = new HashMap<>();
this.halfEdgesData = new HashMap<>();
this.facesDoubleData = new HashMap<>();
this.verticesBooleanData = new HashMap<>();
this.halfEdgesBooleanData = new HashMap<>();
this.facesBooleanData = new HashMap<>();
}
@Override
......@@ -223,6 +235,72 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
dataArray.set(face.getId(), data);
}
@Override
public void setDoubleData(@NotNull final AFace face, @NotNull final String name, final double data) {
if(!facesDoubleData.containsKey(name)) {
DoubleArrayList dataArray = new DoubleArrayList(faces.size());
facesDoubleData.put(name, dataArray);
}
DoubleArrayList dataArray = facesDoubleData.get(name);
assert dataArray.size() == faces.size();
dataArray.set(face.getId(), data);
}
@Override
public void setDoubleData(@NotNull final AVertex vertex, @NotNull final String name, final double data) {
if(!verticesDoubleData.containsKey(name)) {
DoubleArrayList dataArray = new DoubleArrayList(vertices.size());
verticesDoubleData.put(name, dataArray);
}
DoubleArrayList dataArray = verticesDoubleData.get(name);
assert dataArray.size() == vertices.size();
dataArray.set(vertex.getId(), data);
}
@Override
public void setDoubleData(@NotNull final AHalfEdge edge, @NotNull final String name, final double data) {
if(!halfEdgesDoubleData.containsKey(name)) {
DoubleArrayList dataArray = new DoubleArrayList(edges.size());
halfEdgesDoubleData.put(name, dataArray);
}
DoubleArrayList dataArray = halfEdgesDoubleData.get(name);
assert dataArray.size() == edges.size();
dataArray.set(edge.getId(), data);
}
@Override
public void setBooleanData(@NotNull final AFace face, @NotNull final String name, final boolean data) {
if(!facesBooleanData.containsKey(name)) {
BooleanArrayList dataArray = new BooleanArrayList(faces.size());
facesBooleanData.put(name, dataArray);
}
BooleanArrayList dataArray = facesBooleanData.get(name);
assert dataArray.size() == faces.size();
dataArray.set(face.getId(), data);
}
@Override
public void setBooleanData(@NotNull final AVertex vertex, @NotNull final String name, final boolean data) {
if(!verticesBooleanData.containsKey(name)) {
BooleanArrayList dataArray = new BooleanArrayList(vertices.size());
verticesBooleanData.put(name, dataArray);
}
BooleanArrayList dataArray = verticesBooleanData.get(name);
assert dataArray.size() == vertices.size();
dataArray.set(vertex.getId(), data);
}
@Override
public void setBooleanData(@NotNull final AHalfEdge edge, @NotNull final String name, final boolean data) {
if(!halfEdgesBooleanData.containsKey(name)) {
BooleanArrayList dataArray = new BooleanArrayList(edges.size());
halfEdgesBooleanData.put(name, dataArray);
}
BooleanArrayList dataArray = halfEdgesBooleanData.get(name);
assert dataArray.size() == edges.size();
dataArray.set(edge.getId(), data);
}
private void fill(@NotNull final ObjectArrayList<?> data, final int n) {
for(int i = 0; i < n; i++) {
data.add(null);
......@@ -574,6 +652,24 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
}
clone.verticesDoubleData = clonedVerticessDoubleData;
Map<String, BooleanArrayList> clonedFacesBooleanData = new HashMap<>();
for(var entry : facesBooleanData.entrySet()) {
clonedFacesBooleanData.put(entry.getKey(), entry.getValue().clone());
}
clone.facesBooleanData = clonedFacesBooleanData;
Map<String, BooleanArrayList> clonedHalfEdgesBooleanData = new HashMap<>();
for(var entry : halfEdgesBooleanData.entrySet()) {
clonedHalfEdgesBooleanData.put(entry.getKey(), entry.getValue().clone());
}
clone.halfEdgesBooleanData = clonedHalfEdgesBooleanData;
Map<String, BooleanArrayList> clonedVerticessBooleanData = new HashMap<>();
for(var entry : verticesBooleanData.entrySet()) {
clonedVerticessBooleanData.put(entry.getKey(), entry.getValue().clone());
}
clone.verticesBooleanData = clonedVerticessBooleanData;
return clone;
} catch (CloneNotSupportedException e) {
......@@ -694,16 +790,28 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
list.set(vertexMap[i], list.getDouble(i));
list.set(i, tmp);
}
for(var list : verticesBooleanData.values()) {
boolean tmp = list.getBoolean(vertexMap[i]);
list.set(vertexMap[i], list.getBoolean(i));
list.set(i, tmp);
}
}
for(var list : verticesDoubleData.values()) {
if(vertexMap.length < facesDoubleData.size()) {
if(vertexMap.length < verticesDoubleData.size()) {
list.trim(vertexMap.length);
}
}
for(var list : verticesBooleanData.values()) {
if(vertexMap.length < verticesBooleanData.size()) {
list.trim(vertexMap.length);
}
}
for(var list : verticesData.values()) {
if(vertexMap.length < facesDoubleData.size()) {
if(vertexMap.length < verticesData.size()) {
list.trim(vertexMap.length);
}
}
......@@ -720,16 +828,28 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
list.set(edgeMap[i], list.getDouble(i));
list.set(i, tmp);
}
for(var list : halfEdgesBooleanData.values()) {
boolean tmp = list.getBoolean(edgeMap[i]);
list.set(edgeMap[i], list.getBoolean(i));
list.set(i, tmp);
}
}
for(var list : halfEdgesDoubleData.values()) {
if(edgeMap.length < facesDoubleData.size()) {
if(edgeMap.length < halfEdgesDoubleData.size()) {
list.trim(edgeMap.length);
}
}
for(var list : halfEdgesBooleanData.values()) {
if(edgeMap.length < halfEdgesBooleanData.size()) {
list.trim(edgeMap.length);
}
}
for(var list : halfEdgesData.values()) {
if(edgeMap.length < facesDoubleData.size()) {
if(edgeMap.length < halfEdgesData.size()) {
list.trim(edgeMap.length);
}
}
......@@ -746,6 +866,12 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
list.set(faceMap[i], list.getDouble(i));
list.set(i, tmp);
}
for(var list : facesBooleanData.values()) {
boolean tmp = list.getBoolean(faceMap[i]);
list.set(faceMap[i], list.getBoolean(i));
list.set(i, tmp);
}
}
for(var list : facesDoubleData.values()) {
......@@ -754,8 +880,14 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
}
}
for(var list : facesBooleanData.values()) {
if(faceMap.length < facesBooleanData.size()) {
list.trim(faceMap.length);
}
}
for(var list : facesData.values()) {
if(faceMap.length < facesDoubleData.size()) {
if(faceMap.length < facesData.size()) {
list.trim(faceMap.length);
}
}
......
......@@ -319,7 +319,9 @@ public interface IMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
setData(vertex, name, data);
}
//default void setDoubleDataNull
//default void setBooleanNull(@NotNull final V vertex, @NotNull final String name, boolean nil) {}
//default void setDoubleNull(@NotNull final V vertex, @NotNull final String name, double nil) {}
/**
* Returns the data saved on the half-edge in O(1) if there is any and otherwise <tt>Optional.empty()</tt>.
......
package org.vadere.simulator.models.osm.updateScheme;
import org.jetbrains.annotations.NotNull;
import org.vadere.meshing.mesh.gen.IncrementalTriangulation;
import org.vadere.meshing.mesh.gen.MeshPanel;
import org.vadere.meshing.mesh.gen.PFace;
import org.vadere.meshing.mesh.gen.PHalfEdge;
import org.vadere.meshing.mesh.gen.PMesh;
import org.vadere.meshing.mesh.gen.PVertex;
import org.vadere.meshing.mesh.triangulation.triangulator.gen.GenPointSetTriangulator;
import org.vadere.meshing.mesh.inter.IIncrementalTriangulation;
import org.vadere.simulator.models.osm.PedestrianOSM;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.LinkedCellsGrid;
......@@ -30,9 +31,10 @@ public class UpdateSchemeEventDrivenParallel extends UpdateSchemeEventDriven {
private LinkedCellsGrid<PedestrianOSM> linkedCellsGrid;
private boolean[][] locked;
private double pedestrianPotentialWidth;
private Map<PedestrianOSM, PVertex> map;
private PMesh mesh;
private MeshPanel<PVertex, PHalfEdge, PFace> panel;
private Map<PedestrianOSM, PVertex> map;
private IIncrementalTriangulation<PVertex, PHalfEdge, PFace> triangulation;
public UpdateSchemeEventDrivenParallel(@NotNull final Topography topography, @NotNull final double pedestrianPotentialWidth) {
......@@ -74,16 +76,22 @@ public class UpdateSchemeEventDrivenParallel extends UpdateSchemeEventDriven {
int counter = 1;
// event driven update ignores time credits
do{
mesh = new PMesh<>();
Collection<PedestrianPoint> pedPoints = topography.getElements(PedestrianOSM.class)
do {
mesh = new PMesh();
Collection<VPoint> pedPoints = topography.getElements(PedestrianOSM.class)
.stream()
.map(ped -> new PedestrianPoint(ped.getPosition(), ped))
.map(ped -> ped.getPosition())
.collect(Collectors.toList());
GenPointSetTriangulator<PVertex, PHalfEdge, PFace> triangulator
= new GenPointSetTriangulator<>(pedPoints, mesh);
triangulator.generate();
triangulation = new IncrementalTriangulation(mesh);
for(PedestrianOSM pedestrianOSM : topography.getElements(PedestrianOSM.class)) {
PHalfEdge halfEdge = triangulation.insert(pedestrianOSM.getPosition().getX(), pedestrianOSM.getPosition().getY());
PVertex vertex = triangulation.getMesh().getVertex(halfEdge);
triangulation.getMesh().setData(vertex, "pedestrian", pedestrianOSM);
map.put(pedestrianOSM, vertex);
}
triangulation.finish();
if(panel == null) {
panel = new MeshPanel<>(mesh, 1000, 1000);
......@@ -93,9 +101,9 @@ public class UpdateSchemeEventDrivenParallel extends UpdateSchemeEventDriven {
panel.getMeshRenderer().setMesh(mesh);
}
for(PVertex pedestrianPoint : mesh.getVertices()) {
/*for(PVertex pedestrianPoint : mesh.getVertices()) {
map.put(mesh.getPoint(pedestrianPoint).pedestrianOSM, pedestrianPoint);
}
}*/
panel.repaint();
......@@ -151,19 +159,26 @@ public class UpdateSchemeEventDrivenParallel extends UpdateSchemeEventDriven {
logger.info("avoided updates: " + count);
}
private boolean requireUpdate(PedestrianOSM pedestrianOSM) {
private boolean requireUpdate(@NotNull final PedestrianOSM pedestrianOSM) {
PVertex vertex = map.get(pedestrianOSM);
if(mesh.getPoint(vertex).hasChanged()) {
if(hasChanged(pedestrianOSM)) {
return true;
}
for(PVertex v : mesh.getAdjacentVertexIt(vertex)) {
if(mesh.getPoint(v).hasChanged()) {
PedestrianOSM ped = triangulation.getMesh().getData(v, "pedestrian", PedestrianOSM.class).get();
if(hasChanged(ped)) {
return true;
}
}
return false;
}
private boolean hasChanged(@NotNull final PedestrianOSM pedestrianOSM) {
return pedestrianOSM.getLastPosition().equals(pedestrianOSM.getPosition());
}
private class PedestrianPoint implements IPoint {
private final PedestrianOSM pedestrianOSM;
......
......@@ -155,7 +155,7 @@ public interface IPotentialField {
/**
* Generate the mesh, we use the pointer based implementation here.
*/
PEikMesh meshGenerator = new PEikMesh<>(distanceFunc,edgeLengthFunction, 0.7, bbox, holes);
PEikMesh meshGenerator = new PEikMesh(distanceFunc,edgeLengthFunction, 0.7, bbox, holes);
IIncrementalTriangulation<PVertex, PHalfEdge, PFace> triangulation = meshGenerator.generate();
ITimeCostFunction timeCost = TimeCostFunctionFactory.create(
......
......@@ -41,6 +41,6 @@ public class PotentialFieldCalculatorNone implements EikonalSolver {
*/
@Override
public IMesh<?, ?, ?> getDiscretization() {
return new PMesh<>();
return new PMesh();
}
}
......@@ -42,7 +42,7 @@ public class FMMTriangulationExamples {
log.info("start FFM");
solver.initialize();
log.info("FFM finished");
System.out.println(triangulation.getMesh().toPythonTriangulation(p -> p.getPotential()));
System.out.println(triangulation.getMesh().toPythonTriangulation(p -> triangulation.getMesh().getDoubleData(p, EikonalSolverFMMTriangulation.namePotential)));
}
public static IIncrementalTriangulation<
......@@ -84,7 +84,7 @@ public class FMMTriangulationExamples {
}
};
var meshPanel = new PMeshPanel<>(meshImprover.getMesh(), 1000, 800, colorFunction);
var meshPanel = new PMeshPanel(meshImprover.getMesh(), 1000, 800, colorFunction);
meshPanel.display("Combined distance functions " + h0);
while (!meshImprover.isFinished()) {
meshImprover.improve();
......
......@@ -30,11 +30,11 @@ public class PerformanceTriangleFMM {
private static IIncrementalTriangulation<PVertex, PHalfEdge, PFace> createTriangulation() {
IEdgeLengthFunction edgeLengthFunc = p -> 1.0;
PEikMesh meshGenerator = new PEikMesh<>(distanceFunc, edgeLengthFunc, initialEdgeLen, bbox);
PEikMesh meshGenerator = new PEikMesh(distanceFunc, edgeLengthFunc, initialEdgeLen, bbox);
return meshGenerator.generate();
}
private static void solve(EikonalSolverFMMTriangulation<PotentialPoint, PVertex, PHalfEdge, PFace> solver) {
private static void solve(EikonalSolverFMMTriangulation<PVertex, PHalfEdge, PFace> solver) {
long ms = System.currentTimeMillis();
System.out.println("start FFM");
solver.initialize();
......@@ -60,7 +60,7 @@ public class PerformanceTriangleFMM {
/**
* (3) solve the eikonal equation on the mesh
*/
EikonalSolverFMMTriangulation<PotentialPoint, PVertex, PHalfEdge, PFace> solver = new EikonalSolverFMMTriangulation(
EikonalSolverFMMTriangulation<PVertex, PHalfEdge, PFace> solver = new EikonalSolverFMMTriangulation(
new UnitTimeCostFunction(),
triangulation,
targetVertices,
......
......@@ -69,7 +69,7 @@ public class TestFFMNonUniformTriangulation {
private GenEikMesh<PVertex, PHalfEdge, PFace> createEikMesh(
@NotNull final IEdgeLengthFunction edgeLengthFunc,
final double initialEdgeLen) {
IMeshSupplier<PVertex, PHalfEdge, PFace> meshSupplier = () -> new PMesh<>();
IMeshSupplier<PVertex, PHalfEdge, PFace> meshSupplier = () -> new PMesh();
GenEikMesh<PVertex, PHalfEdge, PFace> eikMesh = new GenEikMesh<>(
distanceFunc,
edgeLengthFunc,
......@@ -165,11 +165,11 @@ public class TestFFMNonUniformTriangulation {
log.info("max distance to boundary: " + triangulation.getMesh().getBoundaryVertices().stream().map(p -> Math.abs(distanceFunc.apply(p))).max(Comparator.comparingDouble(d -> d)));
//log.info("L2-Error: " + computeL2Error(triangulation, distanceFunc));
log.info("max error: " + maxError);
log.info("max error-2: " + triangulation.getMesh().getVertices().stream().map(p -> Math.abs(Math.abs(p.getPoint().getPotential() + distanceFunc.apply(p)))).max(Comparator.comparingDouble(d -> d)));
log.info("max error-2: " + triangulation.getMesh().getVertices().stream().map(p -> Math.abs(Math.abs(triangulation.getMesh().getDoubleData(p, EikonalSolverFMMTriangulation.namePotential) + distanceFunc.apply(p)))).max(Comparator.comparingDouble(d -> d)));
log.info("L2-error: " + Math.sqrt(sum / counter));
log.info("L2-error-2: " + Math.sqrt(triangulation.getMesh().getVertices().stream()
.map(p -> Math.abs(Math.abs(p.getPoint().getPotential() + distanceFunc.apply(p))))
.map(p -> Math.abs(Math.abs(triangulation.getMesh().getDoubleData(p, EikonalSolverFMMTriangulation.namePotential) + distanceFunc.apply(p))))
.map(val -> val * val)
.reduce(0.0, (d1, d2) -> d1 + d2) / triangulation.getMesh().getNumberOfVertices()));
//assertTrue(0.0 == solver.getValue(5, 5));
......@@ -326,8 +326,8 @@ public class TestFFMNonUniformTriangulation {
private double computeL2Error(@NotNull final IIncrementalTriangulation<PVertex, PHalfEdge, PFace> triangulation, final IDistanceFunction distanceFunc) {
double sum = 0.0;
for(IVertex vertex : triangulation.getMesh().getVertices()) {
double diff = vertex.getPoint().getPotential() + distanceFunc.apply(vertex);
for(PVertex vertex : triangulation.getMesh().getVertices()) {
double diff = triangulation.getMesh().getDoubleData(vertex, EikonalSolverFMMTriangulation.namePotential) + distanceFunc.apply(vertex);
sum += diff * diff;
}
return Math.sqrt(sum);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment