Skip to content

Commit

Permalink
Merge pull request #102 from Morpho-lang/fixes052
Browse files Browse the repository at this point in the history
Improvements ready for 0.5.2
  • Loading branch information
softmattertheory committed Mar 1, 2022
2 parents eaa8f9c + 1cbac00 commit 4fbe6d2
Show file tree
Hide file tree
Showing 26 changed files with 408 additions and 59 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,8 @@ dkms.conf
test/FailedTests.txt
*.png
manual/src/manual.lyx~
test/vtk/data.case2.vtk
test/vtk/data.case3.0.vtk
examples/qtensor/Qtensor_K_0.01.png
examples/qtensor/Qtensor_K_0.01.png
test/vtk/data.vtk
2 changes: 1 addition & 1 deletion examples/cholesteric/cholesteric.morpho
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ problem.addlocalconstraint(ln, field=nn, target=1)
lnem.pitch = Pi/2

var opt = FieldOptimizer(problem, nn)
opt.linesearch(1000)
opt.conjugategradient(1000)

// Function to visualize a director field
fn visualize(m, nn, dl) {
Expand Down
4 changes: 2 additions & 2 deletions examples/dla/dla.morpho
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import color
import graphics
import povray

var Np = 200 // Number of particles to add
var Np = 100 // Number of particles to add
var r = 0.05 // radius of a particle
var R = 3*r // Initial radius of sphere
var delta = r // Size of step to take
Expand All @@ -20,7 +20,7 @@ fn randompt() {
}

for (n in 1..Np) { // Add particles one-by-one
print n
if (mod(n, 10)==0) print "Added particle no. ${n}"
var x = randompt()
while (true) {
// Move current particle
Expand Down
4 changes: 2 additions & 2 deletions examples/electrostatics/electrostatics.morpho
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ problem.addenergy(lt2, selection=bnd2, prefactor=100)

// Create the optimizer and perform optimization
var opt = FieldOptimizer(problem, phi)
opt.linesearch(100)
opt.conjugategradient(100)

for (i in 1..10) {
// Select elements that have an above average contribution to the energy
Expand All @@ -58,7 +58,7 @@ for (i in 1..10) {
equiangulate(mesh)

// Reminimize
opt.linesearch(1000)
opt.conjugategradient(1000)
}

print "Final mesh has ${mesh.count(2)} elements"
Expand Down
Binary file removed examples/qtensor/Qtensor_K_0.01.png
Binary file not shown.
Binary file removed examples/qtensor/Qtensor_K_1.png
Binary file not shown.
4 changes: 2 additions & 2 deletions examples/qtensor/qtensor.morpho
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ var opt = FieldOptimizer(problem, q_tensor)
// `iters` specifies the number of iterations for the linelearch. From emperical observation, iters=500 works well.
var iters = 500
// Minimize the free energy!
opt.linesearch(iters)
opt.conjugategradient(iters)

// Define some helper functions to plot the result

Expand Down Expand Up @@ -166,7 +166,7 @@ if (refine_adaptively){
// Visualize the refined mesh at each stage
if (visualize_refinement) Show(plotmesh(m, grade=1))

opt.linesearch(iters)
opt.conjugategradient(iters)
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/thomson/thomson.morpho
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ opt.stepsize=0.01/sqrt(Np)
// condition. [This helps condition the problem]
opt.relax(5)
// Now perform gradient descent
opt.linesearch(1000) // Perform up to 1000 iterations of direct gradient descent
opt.conjugategradient(1000) // Perform up to 1000 iterations of direct gradient descent

// Visualize the results
var g = Graphics()
Expand Down
Binary file modified manual/manual.pdf
Binary file not shown.
167 changes: 167 additions & 0 deletions manual/src/Reference/meshgen.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
\hypertarget{meshgen}{%
\section{Meshgen}\label{meshgen}}

The \texttt{meshgen} module is used to create \texttt{Mesh} objects
corresponding to a specified domain. It provides the \texttt{MeshGen}
class to perform the meshing, which are created with the following
arguments:

\begin{lstlisting}
MeshGen(domain, boundingbox)
\end{lstlisting}

Domains are specified by a scalar function that is positive in the
region to be meshed and locally smooth. For example, to mesh the unit
disk:

\begin{lstlisting}
var dom = fn (x) -(x[0]^2+x[1]^2-1)
\end{lstlisting}

A \texttt{MeshGen} object is then created and then used to build the
\texttt{Mesh} like this:

\begin{lstlisting}
var mg = MeshGen(dom, [-1..1:0.2, -1..1:0.2])
var m = mg.build()
\end{lstlisting}

A bounding box for the mesh must be specified as a \texttt{List} of
\texttt{Range} objects, one for each dimension. The increment on each
\texttt{Range} gives an approximate scale for the size of elements
generated.

To facilitate convenient creation of domains, a \texttt{Domain} class is
provided that provides set operations \texttt{union},
\texttt{intersection} and \texttt{difference}.

\texttt{MeshGen} accepts a number of optional arguments:

\begin{itemize}

\item
\texttt{weight} A scalar weight function that controls mesh density.
\item
\texttt{quiet} Set to \texttt{true} to suppress \texttt{MeshGen}
output.
\item
\texttt{method} a list of options that controls the method used.
\end{itemize}

Some method choices that are available include:

\begin{itemize}

\item
\texttt{"FixedStepSize"} Use a fixed step size in optimization.
\item
\texttt{"StartGrid"} Start from a regular grid of points (the
default).
\item
\texttt{"StartRandom"} Start from a randomly generated collection of
points.
\end{itemize}

There are also a number of properties of a \texttt{MeshGen} object that
can be set prior to calling \texttt{build} to control the operation of
the mesh generation:

\begin{itemize}

\item
\texttt{stepsize}, \texttt{steplimit} Stepsize used internally by the
\texttt{Optimizer}
\item
\texttt{fscale} an internal ``pressure''
\item
\texttt{ttol} how far the vertices are allowed to move before
retriangulation
\item
\texttt{etol} energy tolerance for optimization problem
\end{itemize}

\texttt{MeshGen} picks default values that cover a reasonable range of
uses.

\hypertarget{domain}{%
\section{Domain}\label{domain}}

The \texttt{Domain} class is used to conveniently build a domain by
composing simpler elements.

Create a \texttt{Domain} from a scalar function that is positive in the
region of interest:

\begin{lstlisting}
var dom = Domain(fn (x) -(x[0]^2+x[1]^2-1))
\end{lstlisting}

You can pass it to \texttt{MeshGen} to specify the region to mesh:

\begin{lstlisting}
var mg = MeshGen(dom, [-1..1:0.2, -1..1:0.2])
\end{lstlisting}

You can combine \texttt{Domain} objects using set operations
\texttt{union}, \texttt{intersection} and \texttt{difference}:

\begin{lstlisting}
var a = CircularDomain(Matrix([-0.5,0]), 1)
var b = CircularDomain(Matrix([0.5,0]), 1)
var c = CircularDomain(Matrix([0,0]), 0.3)
var dom = a.union(b).difference(c)
\end{lstlisting}

\hypertarget{circulardomain}{%
\section{CircularDomain}\label{circulardomain}}

Conveniently constructs a \texttt{Domain} object correspondiong to a
disk. Requires the position of the center and a radius as arguments.

Create a domain corresponding to the unit disk:

\begin{lstlisting}
var c = CircularDomain([0,0], 1)
\end{lstlisting}

\hypertarget{halfspacedomain}{%
\section{HalfSpaceDomain}\label{halfspacedomain}}

Conveniently constructs a \texttt{Domain} object correspondiong to a
half space defined by a plane at \texttt{x0} and a normal \texttt{n}:

\begin{lstlisting}
var hs = HalfSpaceDomain(x0, n)
\end{lstlisting}

Note \texttt{n} is an ``outward'' normal, so points into the
\emph{excluded} region.

Half space corresponding to the allowed region \texttt{x\textless{}0}:

\begin{lstlisting}
var hs = HalfSpaceDomain(Matrix([0,0,0]), Matrix([1,0,0]))
\end{lstlisting}

Note that \texttt{HalfSpaceDomain}s cannot be meshed directly as they
correspond to an infinite region. They are useful, however, for
combining with other domains.

Create half a disk by cutting a \texttt{HalfSpaceDomain} from a
\texttt{CircularDomain}:

\begin{lstlisting}
var c = CircularDomain([0,0], 1)
var hs = HalfSpaceDomain(Matrix([0,0]), Matrix([-1,0]))
var dom = c.difference(hs)
var mg = MeshGen(dom, [-1..1:0.2, -1..1:0.2], quiet=false)
var m = mg.build()
\end{lstlisting}

\hypertarget{mshgndim}{%
\section{MshGnDim}\label{mshgndim}}

The \texttt{MeshGen} module currently supports 2 and 3 dimensional
meshes. Higher dimensional meshing will be available in a future
release; please contact the developer if you are interested in this
functionality.
148 changes: 148 additions & 0 deletions manual/src/Reference/vtk.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
\hypertarget{vtk}{%
\section{VTK}\label{vtk}}

The vtk module contains classes to allow I/O of meshes and fields using
the VTK Legacy Format.

\hypertarget{vtkexporter}{%
\section{VTKExporter}\label{vtkexporter}}

This class can be used to export the field(s) and/or at a given state to
a single .vtk file. To use it, import the \texttt{vtk} module:

\begin{lstlisting}
import vtk
\end{lstlisting}

Initialize the \texttt{VTKExporter}

\begin{lstlisting}
var vtkE = VTKExporter(obj)
\end{lstlisting}

where \texttt{obj} can either be

\begin{itemize}

\item
A \texttt{Mesh} object: This prepares the Mesh for exporting.
\item
A \texttt{Field} object: This prepares both the Field and the Mesh
associated with it for exporting.
\end{itemize}

Use the \texttt{export} method to export to a VTK file.

\begin{lstlisting}
vtkE.export("output.vtk")
\end{lstlisting}

Optionally, use the \texttt{addfield} method to add one or more fields
before exporting:

\begin{lstlisting}
vtkE.addfield(f, fieldname="f")
\end{lstlisting}

where,

\begin{itemize}

\item
\texttt{f} is the field object to be exported
\item
\texttt{fieldname} is an optional argument that assigns a name to the
field in the VTK file. This name is required to be a character string
without embedded whitespace. If not provided, the name would be either
``scalars'' or ``vectors'' depending on the field type**.
\end{itemize}

** Note that this currently only supports scalar or vector (column
matrix) fields that live on the vertices ( shape \texttt{{[}1,0,0{]}}).
Support for tensorial fields and fields on cells coming soon.

Minimal example:

\begin{lstlisting}
import vtk
import meshtools

var m1 = LineMesh(fn (t) [t,0,0], -1..1:2)

var vtkE = VTKExporter(m1) // Export just the mesh

vtkE.export("mesh.vtk")

var f1 = Field(m1, fn(x,y,z) x)

var g1 = Field(m1, fn(x,y,z) Matrix([x,2*x,3*x]))

vtkE = VTKExporter(f1, fieldname="f") // Export fields

vtkE.addfield(g1, fieldname="g")

vtkE.export("data.vtk")
\end{lstlisting}

\hypertarget{vtkimporter}{%
\section{VTKImporter}\label{vtkimporter}}

This class can be used to import the field(s) and/or the mesh at a given
state from a single .vtk file. To use it, import the \texttt{vtk}
module:

\begin{lstlisting}
import vtk
\end{lstlisting}

Initialize the \texttt{VTKImporter} with the filename

\begin{lstlisting}
var vtkI = VTKImporter("output.vtk")
\end{lstlisting}

Use the \texttt{mesh} method to get the mesh:

\begin{lstlisting}
var mesh = vtkI.mesh()
\end{lstlisting}

Use the \texttt{field} method to get the field:

\begin{lstlisting}
var f = vtkI.field(fieldname)
\end{lstlisting}

Use the \texttt{fieldlist} method to get the list of the names of the
fields contained in the file:

\begin{lstlisting}
print vtkI.fieldlist()
\end{lstlisting}

Use the \texttt{containsfield} method to check whether the file contains
a field by a given \texttt{fieldname}:

\begin{lstlisting}
if (tkI.containsfield(fieldname)) {
...
}
\end{lstlisting}

where \texttt{fieldname} is the name assigned to the field in the .vtk
file

Minimal example:

\begin{lstlisting}
import vtk
import meshtools

var vtkI = VTKImporter("data.vtk")

var m = vtkI.getmesh()

var f = vtkI.getfield("f")

var g = vtkI.getfield("g")
\end{lstlisting}
Binary file modified manual/src/Tutorial/0ExampleMesh/meshgrade0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified manual/src/Tutorial/0ExampleMesh/meshgrade1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified manual/src/Tutorial/0ExampleMesh/meshgrade2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified manual/src/Tutorial/1Mesh/mesh.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified manual/src/Tutorial/2Visualize/out.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified manual/src/Tutorial/2Visualize/selection.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified manual/src/Tutorial/3Refine/out1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified manual/src/Tutorial/3Refine/out2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified manual/src/Tutorial/3Refine/out3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 4fbe6d2

Please sign in to comment.