I am doing some computational fluid dynamics (CFD) simulations for some research, and I have come across a paper that I would like to build upon.
In principle, I am trying to simulate flows and viscosities etc inside a triangular shaped container. Now, some of the cavity-flow and Navier-Stokes equations are quite long. Therefore, some these equations have kindly been publicly written and available in python format here. The code for these equations uses numpy.meshgrid() and numpy.linspace() extensively to produce some rectangular plots in the link. There is nothing wrong with the equations and they are mathematically sound.
However, I would like to replicate these results by simulating them instead inside a triangular container. The plots for these would therefore look like the plots provided on page 28 of this paper. Note here that this is not the rectangular plots with only a triangular subsection plotted, rather the "grid" in this simulation is triangular itself.
My question is whether numpy has a specific feature that would allow for these triangular grids? My evidence of research into this question has led me to scour the documentation regarding non-rectangular arrays, however the closest that I could find was numpy.tril() and numpy.triu(), which still give me rectangular arrays with zeros in the lower and upper triangles of the array respectively. I was wondering if there was any numpy method that allows for the creation of these triangular containers to simulate fluids in.
My last hope would be to create some kind of dictionary, with keys as row numbers, and values as lists which store the column. That way I could create a triangular dictionary. But this would not integrate with the mathematical equations that have written for numpy mentioned previously.
TLDR
How can I use the existing numpy libraries to create triangular grids so that I can have plots that look like this
to then look like this
Related
I have to construct a grid in 2-D space, made of "cells" (finite area). I have a Fortran code which constructed this grid using quadtrees (or octrees, when the need for third dimension arises), that is every cell is a node in the quadtree. The cells cover an approximately right-triangular region, with the y=x line can be imagined as the hypotenuse and other two sides being y=0 and x=k, where k is some constant (An image is attached for reference, how cells are actually present on a 2-D plane).
I need to implement this in Python, but I am not sure if scipy.spatial.KDTree can do everything I want. From what I have tried to read about KD-trees and understand through scipy's docs, scipy.spatial.KDTree mostly deals with tasks related to neighbours and search. But in my case, cells can have more attributes. For example, consider the cells (or leaves) on the "hypotenuse" in the image. I define them to be surface cells. Similarly, the leaves along y=0 are defined as bottom cells. Can I query these surface and bottom cells using scipy.spatial.KDTree? Further I will need all the cells which are part of same "column", as in same value for x (as cells have finite area, you can imagine the x to be the cell centre). Will I be able to access cells columnwise using scipy.spatial.KDTree?
I have looked everywhere but I cannot find tutorials where scipy.spatial.KDTree is used to do more other than just querying for neighbours. Of course, if this is all not possible, I would try to implement the Fortran code into Python, my only fear being the code I write in Python might not be very optimized.
Initially, I did not bother to do tree-like data structures to make grid at all, and just used 2-D numpy arrays. But I ran into some problems. So I think, using trees is important.
I currently have 2 paths generated by a motion planning algorithm in Python. I interpolated into two 3D Polylines with equidistant points. Next I need to find whether these two paths of different lengths intersect (OR even ideally the point(s) at which they get near a certain distance of each other, if any). This is to eventually simulate a collision avoidance algorithm.
After much searching I have found multiple libraries and algorithms that can return points/line intersections of two Polylines, however they are all in 2D. I tried using the Bentley-Ottmann algorithm/python library, the Shapely library, the Geometry3D library, and other 2D solutions found on SO, but none have worked in a 3D environment. Next I tried using a 2D geometry library to find the intersections in the x-y, x-z, and y-z planes individually as shown in the graphs below showing a simple case, but I'm not sure where to go from there or whether that's even the right approach. The Polylines would usually contain 300+ points.
Any help pointing me towards a 3D algorithm or simple adjustments to make to the 2D libraries work in 3D would be really appreciated!
3D graph view, x-y view, z-y view.
I'm a wee bit stuck.
I have a 3D point cloud (an array of (n,3) vertices), in which I am trying to generate a 3D triangular mesh from. So far I have had no luck.
The format my data comes in:
(x,y) values in regularly spaced (z) intervals. Think of the data as closed loop planar contours stored slice by slice in the z direction.
The vertices in my data must be absolute positions for the mesh triangles (i.e. I don't want them to be smoothed out such that the volume begins to change shape, but linear interpolation between the layers is fine).
Illustration:
Z=2. : ..x-------x... <- Contour 2
Z=1.5: ...\......|... <- Join the two contours into a mesh.
Z=1. : .....x----x... <- Contour 1
Repeat for n slices, end up with an enclosed 3D triangular mesh.
Things I have tried:
Using Open3D:
The rolling ball (pivot) method can only get 75% of the mesh completed and leaves large areas incomplete (despite a range of ball sizes). It has particular problems at the top and bottom slices where there tends to be large gaps in the middle (i.e. a flat face).
The Poisson reconstruction method smooths out the volume too much and I no longer have an accurate representation of the volume. This occurs at all depths from 3-12.
CGAL:
I cannot get this to work for the life of me. SWIG is not very good, the implementation of CGAL using SWIG is also not very good.
There are two PyBind implementations of CGAL however they have not incorporated the 3D triangulation libraries from CGAL.
Explored other modules like PyMesh, TriMesh, TetGen, Scikit-Geometry, Shapely etc. etc. I may have missed the answer somewhere along the line.
Given that my data is a list of closed-loop planar contours, it seems as though there must be some simple solution to just "joining" adjacent slice contours into one big 3d mesh. Kind of like you would in blender.
There are non-python solutions (like MeshLab) that may well solve these problems, but I require a python solution. Does anyone have any ideas? I've had a bit of a look into VTK and ITK but haven't found exactly what I'm looking for as of yet.
I'm also starting to consider that maybe I can interpolate intermediate contours between slices, and fill the contours on the top and bottom with vertices to make the data a bit more "pivot ball" method friendly.
Thank you in advance for any help, it is appreciated.
If there is a good way of doing this that isn't coded yet, I promise to code it and make it available for people in my situation :)
Actually there are two ways of having meshlab functionality in python:
The first is MeshLabXML (https://github.com/3DLIRIOUS/MeshLabXML ) a third party, is a Python scripting interface to meshlab scripting interface
the second is PyMeshLab (https://github.com/cnr-isti-vclab/PyMeshLab ) an ongoing effort done by the MeshLab authors, (currently in alpha stage) to have a direct Python bindings to all the meshlab filters
There is a very neat paper titled "Technical Note: an algorithm and software for conversion of radiotherapy contour‐sequence data to ready‐to‐print 3D structures" in the Journal of Medical Physics that describes this problem quite nicely. No python packages are required, however it is more easily implemented with numpy. No need for any 3D packages.
A useful excerpt is provided:
...
The number of slices (2D contours) constituting the specified structure is determined.
The number of points in each slice is determined.
Cartesian coordinates of each of the points in each slice are extracted and stored within dedicated data structures...
Numbers of points in each slice (curve) are re‐arranged in such a way, that the starting points (points with indices 0) are the closest points between the subsequent slices. Renumeration starts at point 0, slice 0 (slice with the lowest z coordinate).
Orientation (i.e., the direction determined by the increasing indices of points with relation to the interior/exterior of the curve) of each curve is determined. If differences between slices are found, numbering of points in non‐matching curves (and thus, orientation) is reversed.
The lateral surface of the considered structure is discretized. Points at the neighboring layers are arranged into threes, constituting triangular facets for the STL file. For each triangle the closest points with the subsequent indices from each layer are connected.
Lower and upper base surfaces of the considered structure are discretized. The program iterates over every subsequent three points on the curve and checks if they belong to a convex part of the edge. If yes, they are connected into a facet, and the middle point is removed from further iterations.
So basically it's a problem of aligning datasets in each slice to the nearest value of each slice. Then aligning the orientation of each contour. Then joining the points between two layers based on distance.
The paper also provides code to do this (for a DICOM file), however I re-wrote it myself and it works a charm.
I hope this helps others! Make sure you credit the author's in any work you do that uses this.
A recent feature of pymadcad can do things like this, not sure through if it fits your exact expectation in term of "pivot ball" or such things, checkout the doc for blending
Starting from a list of outlines, it can generate blended surfaces to join them:
For your purpose, I guess the best is one of:
blendpair(line1, line2)
junction(*lines)
I have two sets of data points; effectively, one is from a preimage and the other from its image, but I do not know the rule between the two. This rule/function is nonlinear.
I've collected many data points of corresponding locations on both images, and I was wondering if anyone knew of a way to find a more complete mapping. That is, does anyone know the best way to find a mapping from R^2 to R^2 with an extensive set of sample points. This mapping is one-to-one and onto.
My goal is to use the data I've found to find a polynomial function that takes in some x,y coordinate from the preimage, and outputs the shifted coordinates.
edit: I have sample points along the domain and their corresponding points in the image, but not for every point in the domain. I want to be able to input any point (only integer values) in the domain and output the shifted point.
I don't think polynomial is easy (or easy to guarantee is a bijection). The obvious thing to do is to
Construct the delaunay triangulation of the known points in the domain.
For each delaunay triangle the mapping is just the linear mapping which interpolates the map on the vertices.
Then, when you have a random point, look up its delaunay triangle, and apply the requisite map.
I believe that all of the above can be done via scipy.spatial.delaunay.
The transformation you're trying to find sounds a lot like what's accomplished in Geographic Information Systems using a technique called rubber-sheeting https://en.wikipedia.org/wiki/Rubbersheeting
Igor Rivin's description of a process using a Delaunay triangulation is pretty much the solution that's used in such systems. Some systems will use a Barycentric coordinate system rather than a linear mapping to try to reduce the appearance of triangle-related artifacts in the transformed image.
What you are describing also sounds a bit like the "morphing" special effect used in video. Maybe a web search on that topic would turn up some leads for you.
I have began to write a programme that calculates solutions to Schrödingers equation in 2D using the finite differences method. I would like to display the solutions graphically using a contour plot or some other graphical display by taking in user input for the dimensions and number of grid points.
I have simplified the Schrödinger equation by setting hbar^2/2m to 1 and setting the potentiel (V) equal to 0 which gives:
-(dψ^2/dx^2 + dψ^2/dy^2) = E*ψ
Using the finite differences method the left hand side of the equation becomes the matrix of the form:
enter image description here
So this now becomes an eigenvalue problem which is the part I’m having trouble implementing.
After using the command np.linalg.eig to get the eigenvalues and eigenvectors I’m unsure of how to code a graphical interpretation of these solutions in 2D. Any help will be much appreciated.
Basically I want to use the eigenvalues and eigenvector to graphically display the solutions I just don’t know which to use and how to code it.
Cheers
You need to be more precise in your question. You say you don't know which to use, eigenvalues or eigenvectors, but that depends on what you want to plot.
Do you want to plot the energies of the quantum mechanical system? Those are represented by the eigenvalues of the Hamiltonian operator.
Do you want to plot the states that you observe your system to be in when you measure the energy? Those are given by the eigenvectors.
After finding the relevant quantity, what is it you want to plot? If it's just the energies, then you can use matplotlib's heatmap tools to show the energy as a function of x and y. If it's the states of definite energy, then you could use some of the vector field tools that matplotlib provides.