Regenerated branch

This commit is contained in:
Jose Luis Cercós Pita 2013-05-20 09:08:43 -04:00
parent 37d1696e16
commit 0a930d4c1a
51 changed files with 7305 additions and 401 deletions

View File

@ -21,6 +21,14 @@ SET(ShipExamples_SRCS
)
SOURCE_GROUP("shipexamples" FILES ${ShipExamples_SRCS})
SET(ShipOpenCL_SRCS
resources/opencl/matrixGen.cl
resources/opencl/jacobi.cl
resources/opencl/minres.cl
resources/opencl/lsqr.cl
)
SOURCE_GROUP("shipopencl" FILES ${ShipOpenCL_SRCS})
SET(ShipLoadExample_SRCS
shipLoadExample/__init__.py
shipLoadExample/TaskPanel.py
@ -107,12 +115,18 @@ SET(SimRun_SRCS
simRun/TaskPanel.ui
simRun/clSim/__init__.py
simRun/clSim/initialization.py
simRun/clSim/Utils.py
simRun/clSim/matrixGen.py
simRun/clSim/BEMsolver.py
simRun/clSim/evolution.py
simRun/clSim/clUtils.py
simRun/clSim/bem_jacobi_cl.py
simRun/clSim/bem_minres_cl.py
simRun/clSim/bem_lsqr_cl.py
simRun/Sim/__init__.py
simRun/Sim/initialization.py
simRun/Sim/matrixGen.py
simRun/Sim/computeSources.py
simRun/Sim/fsEvolution.py
simRun/Sim/BEMsolver.py
simRun/Sim/evolution.py
)
SOURCE_GROUP("simrun" FILES ${SimRun_SRCS})
@ -123,7 +137,7 @@ SET(SimPost_SRCS
)
SOURCE_GROUP("simpost" FILES ${SimPost_SRCS})
SET(all_files ${ShipMain_SRCS} ${ShipIcons_SRCS} ${ShipExamples_SRCS} ${ShipLoadExample_SRCS} ${ShipCreateShip_SRCS} ${ShipOutlineDraw_SRCS} ${ShipAreasCurve_SRCS} ${ShipHydrostatics_SRCS} ${ShipUtils_SRCS} ${ShipWeights_SRCS} ${ShipCreateTank_SRCS} ${ShipGZ_SRCS} ${SimCreate_SRCS} ${SimRun_SRCS} ${SimPost_SRCS})
SET(all_files ${ShipMain_SRCS} ${ShipIcons_SRCS} ${ShipExamples_SRCS} ${ShipOpenCL_SRCS} ${ShipLoadExample_SRCS} ${ShipCreateShip_SRCS} ${ShipOutlineDraw_SRCS} ${ShipAreasCurve_SRCS} ${ShipHydrostatics_SRCS} ${ShipUtils_SRCS} ${ShipWeights_SRCS} ${ShipCreateTank_SRCS} ${ShipGZ_SRCS} ${SimCreate_SRCS} ${SimRun_SRCS} ${SimPost_SRCS})
ADD_CUSTOM_TARGET(Ship ALL
SOURCES ${all_files}
@ -143,6 +157,12 @@ INSTALL(
DESTINATION
Mod/Ship/resources/examples
)
INSTALL(
FILES
${ShipOpenCL_SRCS}
DESTINATION
Mod/Ship/resources/opencl
)
INSTALL(
FILES
${ShipLoadExample_SRCS}

View File

@ -15,6 +15,10 @@ nobase_data_DATA = \
resources/examples/wigley.fcstd \
resources/examples/wigley_katamaran.fcstd \
resources/icons/Ico.xpm \
resources/opencl/matrixGen.cl \
resources/opencl/jacobi.cl \
resources/opencl/minres.cl \
resources/opencl/lsqr.cl \
shipLoadExample/__init__.py \
shipLoadExample/TaskPanel.py \
shipLoadExample/TaskPanel.ui \
@ -60,12 +64,18 @@ nobase_data_DATA = \
simRun/TaskPanel.ui \
simRun/clSim/__init__.py \
simRun/clSim/initialization.py \
simRun/clSim/Utils.py \
simRun/clSim/matrixGen.py \
simRun/clSim/BEMsolver.py \
simRun/clSim/evolution.py \
simRun/clSim/clUtils.py \
simRun/clSim/bem_jacobi_cl.py \
simRun/clSim/bem_minres_cl.py \
simRun/clSim/bem_lsqr_cl.py \
simRun/Sim/__init__.py \
simRun/Sim/initialization.py \
simRun/Sim/matrixGen.py \
simRun/Sim/computeSources.py \
simRun/Sim/fsEvolution.py \
simRun/Sim/BEMsolver.py \
simRun/Sim/evolution.py \
simPost/__init__.py \
simPost/TaskPanel.py \
simPost/TaskPanel.ui

View File

@ -62,19 +62,38 @@ class FreeSurfaceFace:
self.area = area
class ShipSimulation:
def __init__(self, obj, fsMeshData, waves):
def __init__(self, obj, fsMeshData, waves, error):
""" Creates a new simulation instance on active document.
@param obj Created Part::FeaturePython object.
@param h Sea water level.
@param fsMeshData [L,B,N] Free surface mesh data, with lenght
(x), Beam (y) and desired number of points.
@param waves [[A,T,phi,heading],] Waves involved
@param waves [[A,T,phi,heading],] Waves involved.
@param error Relation between the minimum and the maximum Green's function values.
"""
# Add uniqueness property to identify Tank instances
tooltip = str(QtGui.QApplication.translate("Ship","True if is a valid ship simulation instance",
None,QtGui.QApplication.UnicodeUTF8))
obj.addProperty("App::PropertyBool","IsShipSimulation","ShipSimulation", tooltip).IsShipSimulation=True
# Store general data
tooltip = str(QtGui.QApplication.translate("Ship","Free surface length in the x direction",
None,QtGui.QApplication.UnicodeUTF8))
obj.addProperty("App::PropertyFloat","L","ShipSimulation", tooltip).L=fsMeshData[0]
tooltip = str(QtGui.QApplication.translate("Ship","Free surface length in the y direction",
None,QtGui.QApplication.UnicodeUTF8))
obj.addProperty("App::PropertyFloat","B","ShipSimulation", tooltip).B=fsMeshData[1]
tooltip = str(QtGui.QApplication.translate("Ship","Free surface number of elements at x direction",
None,QtGui.QApplication.UnicodeUTF8))
obj.addProperty("App::PropertyInteger","FS_Nx","ShipSimulation", tooltip).FS_Nx=fsMeshData[2]
tooltip = str(QtGui.QApplication.translate("Ship","Free surface number of elements at y direction",
None,QtGui.QApplication.UnicodeUTF8))
obj.addProperty("App::PropertyInteger","FS_Ny","ShipSimulation", tooltip).FS_Ny=fsMeshData[3]
tooltip = str(QtGui.QApplication.translate("Ship","Relative error of the Green's function",
None,QtGui.QApplication.UnicodeUTF8))
obj.addProperty("App::PropertyFloat","error","ShipSimulation", tooltip).error=error
# Compute free surface mesh
self.createFSMesh(obj,fsMeshData)
self.createVirtualFS(obj,fsMeshData,error)
self.computeWaves(obj,waves)
# Store waves
tooltip = str(QtGui.QApplication.translate("Ship","Waves (Amplitude,period,phase)",
@ -112,8 +131,8 @@ class ShipSimulation:
def createFSMesh(self, obj, fsMeshData):
""" Create or modify free surface mesh.
@param obj Created Part::FeaturePython object.
@param fsMeshData [L,B,N] Free surface mesh data, with lenght
(x), Beam (y) and desired number of points.
@param fsMeshData [L,B,Nx,Ny] Free surface mesh data, with lenght
(x), Breath (y) and desired number of points at each direction.
"""
# Study input object
try:
@ -130,29 +149,17 @@ class ShipSimulation:
FreeCAD.Console.PrintError(msg + '\n')
return
# Get areas and number of elements per direction
L = fsMeshData[0]
B = fsMeshData[1]
N = fsMeshData[2]
A = L*B
L = fsMeshData[0]
B = fsMeshData[1]
nx = fsMeshData[2]
ny = fsMeshData[3]
N = nx*ny
A = L*B
area = A/N
l = sqrt(area)
b = sqrt(area)
nx = int(round(L / l))
ny = int(round(B / b))
l = L/nx
b = B/ny
# Start data fields if not already exist
props = obj.PropertiesList
try:
props.index("FS_Nx")
except ValueError:
tooltip = str(QtGui.QApplication.translate("Ship","Free surface number of elements at x direction",
None,QtGui.QApplication.UnicodeUTF8))
obj.addProperty("App::PropertyInteger","FS_Nx","ShipSimulation", tooltip).FS_Nx=0
try:
props.index("FS_Ny")
except ValueError:
tooltip = str(QtGui.QApplication.translate("Ship","Free surface number of elements at y direction",
None,QtGui.QApplication.UnicodeUTF8))
obj.addProperty("App::PropertyInteger","FS_Ny","ShipSimulation", tooltip).FS_Ny=0
try:
props.index("FS_Position")
except ValueError:
@ -172,6 +179,8 @@ class ShipSimulation:
None,QtGui.QApplication.UnicodeUTF8))
obj.addProperty("App::PropertyVectorList","FS_Normal","ShipSimulation", tooltip).FS_Normal=[]
# Fill data
obj.L = L
obj.B = B
obj.FS_Nx = nx
obj.FS_Ny = ny
pos = []
@ -186,6 +195,68 @@ class ShipSimulation:
obj.FS_Area = areas[:]
obj.FS_Normal = normal[:]
def createVirtualFS(self, obj, fsMeshData, error):
""" Computes the number of required extended free surfaces.
@param obj Created Part::FeaturePython object.
@param fsMeshData [L,B,Nx,Ny] Free surface mesh data, with lenght
(x), Breath (y) and desired number of points at each direction.
@param error Relation between the minimum and the maximum Green's function values.
"""
# Study input object
try:
props = obj.PropertiesList
props.index("IsShipSimulation")
if not obj.IsShipSimulation:
msg = QtGui.QApplication.translate("ship_console", "Object is not a valid ship simulation",
None,QtGui.QApplication.UnicodeUTF8)
FreeCAD.Console.PrintError(msg + '\n')
return
except ValueError:
msg = QtGui.QApplication.translate("ship_console", "Object is not a ship simulation",
None,QtGui.QApplication.UnicodeUTF8)
FreeCAD.Console.PrintError(msg + '\n')
return
# Get dimensions of the elements
L = fsMeshData[0]
B = fsMeshData[1]
nx = fsMeshData[2]
ny = fsMeshData[3]
dx = L / nx
dy = B / ny
# Compute maximum Green's function considering flat free surface
Gmax = dx*asinh(dy/dx) + dy*asinh(dx/dy)
# Locate the distance (number of free surface) to get the minimum required value
Gmin = error*Gmax
x = (L-dx)/2.0
Nx = 0
G = Gmin + 1.0
while(G > Gmin):
x = x + L
Nx = Nx + 1
G = 1.0 / (4.0*pi * x)
y = (B-dy)/2.0
Ny = 0
G = Gmin + 1.0
while(G > Gmin):
y = y + L
Ny = Ny + 1
G = 1.0 / (4.0*pi * y)
# Register computed data
try:
props.index("Sea_Nx")
except ValueError:
tooltip = str(QtGui.QApplication.translate("Ship","Number of repetitions of the free surface at x direction",
None,QtGui.QApplication.UnicodeUTF8))
obj.addProperty("App::PropertyInteger","Sea_Nx","ShipSimulation", tooltip).Sea_Nx=0
try:
props.index("Sea_Ny")
except ValueError:
tooltip = str(QtGui.QApplication.translate("Ship","Number of repetitions of the free surface at y direction",
None,QtGui.QApplication.UnicodeUTF8))
obj.addProperty("App::PropertyInteger","Sea_Ny","ShipSimulation", tooltip).Sea_Ny=0
obj.Sea_Nx = Nx
obj.Sea_Ny = Ny
def computeWaves(self, obj, waves):
""" Add waves effect to free surface mesh positions.
@param obj Created Part::FeaturePython object.
@ -215,21 +286,14 @@ class ShipSimulation:
"""
nx = obj.FS_Nx
ny = obj.FS_Ny
mesh = FSMesh(obj)
# Create BSpline surface
surf = Part.BSplineSurface()
for i in range(1,nx-1):
u = i / float(nx-1)
surf.insertUKnot(u,i,0.000001)
for i in range(1,ny-1):
v = i / float(ny-1)
surf.insertVKnot(v,i,0.000001)
mesh = FSMesh(obj)
surf = Part.BSplineSurface()
pos = []
for i in range(0,nx):
pos.append([])
for j in range(0,ny):
u = i / float(nx-1)
v = j / float(ny-1)
point = mesh[i][j].pos
surf.movePoint(u,v,point,i+1,i+1,j+1,j+1)
pos[i].append(mesh[i][j].pos)
surf.interpolate(pos)
return surf.toShape()
class ViewProviderShipSimulation:
@ -694,3 +758,4 @@ def FSMesh(obj, recompute=False):
obj.FS_Normal[j + i*ny] = faces[i][j].normal
obj.FS_Area[j + i*ny] = faces[i][j].area
return faces

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2011, 2012 *
* Jose Luis Cercos Pita <jlcercos@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License (LGPL) *
* as published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* for detail see the LICENCE text file. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this program; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
*/
/** Compute residuals of the solution stimator for a linear system.
* @param A Linear system matrix.
* @param B Linear system independent term.
* @param X Solution estimation.
* @param R Residuals.
* @param n Linear system dimension.
*/
__kernel void r(__global float* A,
__global float* B,
__global float* X,
__global float* R,
unsigned int n)
{
// find position in global arrays
unsigned int i = get_global_id(0);
unsigned int j;
if(i >= n)
return;
// Evaluate the row
R[i] = B[i];
for(j=0;j<n;j++){
R[i] -= A[j + i*n]*X[j];
}
}
/** Solve a linear system using Jacobi iterative method.
* @param A Linear system matrix.
* @param B Linear system independent term.
* @param X0 Solution of the previous iteration.
* @param X Solution of the actual iteration.
* @param w Relaxation factor.
* @param n Linear system dimension.
*/
__kernel void jacobi(__global float* A,
__global float* B,
__global float* X0,
__global float* X,
float w,
unsigned int n)
{
// find position in global arrays
unsigned int i = get_global_id(0);
unsigned int j;
if(i >= n)
return;
// Evaluate the row
X[i] = B[i];
for(j=0;j<n;j++){
if(i == j){
continue;
}
X[i] += A[j + i*n]*X0[j];
}
X[i] *= w/A[i + i*n];
X[i] += (1.f - w)*X0[i];
}

View File

@ -0,0 +1,186 @@
/*
* Copyright (c) 2011, 2012 *
* Jose Luis Cercos Pita <jlcercos@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License (LGPL) *
* as published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* for detail see the LICENCE text file. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this program; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
*/
/** Get matrix column.
* @param A Linear system matrix.
* @param v Column vector (output).
* @param col Column index.
* @param n Linear system dimension.
*/
__kernel void column(__global float* A,
__global float* v,
unsigned int col,
unsigned int n)
{
// find position in global arrays
unsigned int i = get_global_id(0);
if(i >= n)
return;
v[i] = A[i + col*n];
}
/** Performs matrix column product by a constant.
* @param A Linear system matrix.
* @param c Constant.
* @param col Column index.
* @param n Linear system dimension.
*/
__kernel void prod_c_column(__global float* A,
float c,
unsigned int col,
unsigned int n)
{
// find position in global arrays
unsigned int i = get_global_id(0);
if(i >= n)
return;
A[i + col*n] *= c;
}
/** Compute residuals of the solution stimator for a linear system.
* @param A Linear system matrix.
* @param B Linear system independent term.
* @param X Solution estimation.
* @param R Residuals.
* @param n Linear system dimension.
*/
__kernel void r(__global float* A,
__global float* B,
__global float* X,
__global float* R,
unsigned int n)
{
// find position in global arrays
unsigned int i = get_global_id(0);
unsigned int j;
if(i >= n)
return;
// Evaluate the row
R[i] = B[i];
for(j=0;j<n;j++){
R[i] -= A[j + i*n]*X[j];
}
}
/** Compute inner product between a matrix and a vector.
* @param A Matrix.
* @param X Vector.
* @param Y Result.
* @param n Linear system dimension.
*/
__kernel void dot_mat_vec(__global float* A,
__global float* X,
__global float* Y,
unsigned int n)
{
// find position in global arrays
unsigned int i = get_global_id(0);
unsigned int j;
if(i >= n)
return;
// Evaluate the row
Y[i] = 0.f;
for(j=0;j<n;j++){
Y[i] += A[j + i*n]*X[j];
}
}
/** Compute inner product between a transposed matrix and a vector.
* @param A Matrix.
* @param X Vector.
* @param Y Result.
* @param n Linear system dimension.
*/
__kernel void dot_matT_vec(__global float* A,
__global float* X,
__global float* Y,
unsigned int n)
{
// find position in global arrays
unsigned int i = get_global_id(0);
unsigned int j;
if(i >= n)
return;
// Evaluate the row
Y[i] = 0.f;
for(j=0;j<n;j++){
Y[i] += A[i + j*n]*X[j];
}
}
/** Create u vector for the next iteration.
* @note u loads beta inside, you must compute
* the norm and divide him.
* @param A Linear system matrix.
* @param u0 u vector from previous step.
* @param v0 v vector from previous step.
* @param u Looked u vector for next step.
* @param alpha \$ \alpha_{i} \$.
* @param n Linear system dimension.
*/
__kernel void u(__global float* A,
__global float* u0,
__global float* v0,
__global float* u,
float alpha,
unsigned int n)
{
// find position in global arrays
unsigned int i = get_global_id(0);
unsigned int j;
if(i >= n)
return;
// Evaluate the row
u[i] = - alpha * u0[i];
for(j=0;j<n;j++){
u[i] += A[j + i*n]*v0[j];
}
}
/** Create v vector for the next iteration.
* @note v loads alpha inside, you must compute
* the norm and divide him.
* @param A Linear system matrix.
* @param u u vector for next step.
* @param v0 v vector from previous step.
* @param v Looked v vector for next step.
* @param beta \$ \beta_{i+1} \$.
* @param n Linear system dimension.
*/
__kernel void v(__global float* A,
__global float* u,
__global float* v0,
__global float* v,
float beta,
unsigned int n)
{
// find position in global arrays
unsigned int i = get_global_id(0);
unsigned int j;
if(i >= n)
return;
// Evaluate the row
v[i] = - beta * v0[i];
for(j=0;j<n;j++){
v[i] += A[i + j*n]*u[j];
}
}

View File

@ -0,0 +1,326 @@
/*
* Copyright (c) 2011, 2012 *
* Jose Luis Cercos Pita <jlcercos@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License (LGPL) *
* as published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* for detail see the LICENCE text file. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this program; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
*/
#ifndef M_PI
#define M_PI 3.14159265f
#endif
#ifndef _NG_
#define _NG_ 16
#endif
/** Compute \$G_{ab}\$ effect: \n
* \$ G_{ab} = \frac{1}{4 \pi \vert \mathbf{r} \vert } \$
* @param r Union vector \$ \mathbf{r}_{ab} \$
*/
float G_val(float4 r)
{
return 1.f / ( 4.f*M_PI * length(r) );
}
/** Compute \$H_{ab}\$ effect: \n
* \$ H_{ab} = \frac{\mathbf{r}}{4 \pi \vert \mathbf{r} \vert^3} \cdot n_b \$
* @param r Union vector \$ \mathbf{r}_{ab} \$
* @param n Element normal \$ n_b \$
*/
float H_val(float4 r,
float4 n)
{
return - dot(r,n) / (4.f*M_PI * pow(dot(r,r),1.5f));
}
/** Computes z coordinate due to the waves superposition
* for a desired position.
* @param w Array of waves.
* @param p Point to compute.
* @param t Simulation time.
* @param nW Number of waves.
* @return z coordinate.
*/
float waves_z(__global float4* w, float4 p, float t, unsigned int nW)
{
/*
return 0.f;
*/
unsigned int i;
float z = 0.f;
for(i=0;i<nW;i++){
float omega = 2.f * M_PI / w[i].y;
float k = omega * omega / 9.81f;
float beta = w[i].w * M_PI / 180.f;
float l = p.x*cos(beta) + p.y*sin(beta);
z += w[i].x * sin(k*l - omega*t + w[i].z);
}
return z;
}
/** Computes velocity potential due to the waves superposition
* for a desired position.
* @param w Array of waves.
* @param p Point to compute.
* @param t Simulation time.
* @param nW Number of waves.
* @return z coordinate.
*/
float waves_phi(__global float4* w, float4 p, float t, unsigned int nW)
{
/*
float4 r;
r.w = 0.f;
r.xy = p.xy;
r.z = 15.f;
return G_val(r);
*/
unsigned int i;
float z = 0.f;
for(i=0;i<nW;i++){
float omega = 2.f * M_PI / w[i].y;
float k = omega * omega / 9.81f;
float beta = w[i].w * M_PI / 180.f;
float l = p.x*cos(beta) + p.y*sin(beta);
z -= w[i].x*omega/k * cos(k*l - omega*t + w[i].z)*exp(k*p.z);
}
return z;
}
/** Computes velocity potential gradient z coordinate
* due to the waves superposition
* for a desired position.
* @param w Array of waves.
* @param p Point to compute.
* @param t Simulation time.
* @param nW Number of waves.
* @return z coordinate.
*/
float waves_gradphi(__global float4* w, float4 p, float t, unsigned int nW)
{
/*
float4 r,n;
r.w = 0.f;
r.xy = p.xy;
r.z = 15.f;
n.x = 0.f;
n.y = 0.f;
n.z = 1.f;
n.w = 0.f;
return H_val(r,n);
*/
unsigned int i;
float z = 0.f;
for(i=0;i<nW;i++){
float omega = 2.f * M_PI / w[i].y;
float k = omega * omega / 9.81f;
float beta = w[i].w * M_PI / 180.f;
float l = p.x*cos(beta) + p.y*sin(beta);
z -= w[i].x*omega * cos(k*l - omega*t + w[i].z)*exp(k*p.z);
}
return z;
}
/** Computes \$G_{ab}\$ and \$H_{ab}\$ in the case that \$a = b\$ \n
* \$ G_{ab} = \frac{1}{4 \pi \vert \mathbf{r} \vert } \$
* \$ H_{ab} = \frac{\mathbf{r}}{4 \pi \vert \mathbf{r} \vert^3} \cdot n_b - \frac{1}{2} \$
* @param positions Array of points of the free surface
* @param w Array of waves data (Amplitude,period,phase,heading)
* @param normals Element normals
* @param I x index of the point to compute.
* @param J y index of the point to compute.
* @param L Free surface length in the x direction.
* @param B Free surface length in the y direction.
* @param dx Distance between element centers in the x direction.
* @param dy Distance between element centers in the x direction.
* @param t Simulation time.
* @param nx Free surface points in the x direction.
* @param ny Free surface points in the y direction.
* @param nW Number of waves.
*/
float2 GH(__global float4* positions,
__global float4* w,
__global float4* normals,
unsigned int I, unsigned int J,
float L, float B,
float dx, float dy,
float t,
unsigned int nx,
unsigned int ny,
unsigned int nW)
{
__private float4 P[9];
__private float K[9];
unsigned int i,j;
float4 p = positions[I*ny + J];
float4 n = normals[I*ny + J];
float Dx = dx / _NG_;
float Dy = dy / _NG_;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
P[i*3+j].x = p.x + (i-1)*dx;
P[i*3+j].y = p.y + (j-1)*dy;
if( (P[i*3+j].x > -0.5*L) &&
(P[i*3+j].x < 0.5*L) &&
(P[i*3+j].y > -0.5*B) &&
(P[i*3+j].y < 0.5*B))
P[i*3+j].z = positions[(I-1+i)*ny + (J-1+j)].z;
else
P[i*3+j].z = waves_z(w, P[i*3+j], t, nW);
P[i*3+j].w = 0.f;
}
}
// Get SPline surface coeffs
K[0] = P[0].z; // k_{0}
K[1] = 4*P[3].z - P[6].z - 3*P[0].z; // k_{u}
K[2] = 4*P[1].z - P[2].z - 3*P[0].z; // k_{v}
K[3] = P[8].z - 4*P[7].z + 3*P[6].z +
3*P[2].z - 12*P[1].z + 9*P[0].z +
-4*P[5].z + 16*P[4].z - 12*P[3].z; // k_{uv}
K[4] = 2*P[6].z + 2*P[0].z - 4*P[3].z; // k_{uu}
K[5] = 2*P[2].z + 2*P[0].z - 4*P[1].z; // k_{vv}
K[6] = -2*P[8].z + 8*P[7].z - 6*P[6].z +
-2*P[2].z + 8*P[1].z - 6*P[0].z +
4*P[5].z - 16*P[4].z + 12*P[3].z; // k_{uuv}
K[7] = -2*P[8].z + 4*P[7].z - 2*P[6].z +
-6*P[2].z + 12*P[1].z - 6*P[0].z +
8*P[5].z - 16*P[4].z + 8*P[3].z; // k_{uuv}
K[8] = 4*P[8].z - 8*P[7].z + 4*P[6].z +
4*P[2].z - 8*P[1].z + 4*P[0].z +
-8*P[5].z + 16*P[4].z - 8*P[3].z; // k_{uuvv}
// Loop around the point p collecting the integral
float2 gh;
gh.x = 0.0f;
gh.y = -0.5f;
for(i=0;i<_NG_;i++){
for(j=0;j<_NG_;j++){
float4 p_a;
float u,v;
p_a.x = positions[I*ny + J].x - 0.5f*dx + (i+0.5f)*Dx;
p_a.y = positions[I*ny + J].y - 0.5f*dy + (j+0.5f)*Dy;
u = (p_a.x - P[0].x) / (P[6].x - P[0].x);
v = (p_a.y - P[0].y) / (P[2].y - P[0].y);
p_a.z = K[0] + K[1]*u + K[2]*v + K[3]*u*v +
K[4]*u*u + K[5]*v*v + K[6]*u*u*v +
K[7]*u*v*v + K[8]*u*u*v*v;
p_a.w = 1.f;
gh.x += G_val(p_a - p)*Dx*Dy;
// For some reason H is not well integrated
// gh.y += H_val(p_a - p, n)*Dx*Dy;
}
}
return gh;
}
/** Compute Linear system matrix. Desingularized sources must taken into account.
* @param A Linear system matrix.
* @param B Independent term for velocity potentials.
* @param positions Elements points.
* @param areas Elements area.
* @param normals Elements normals.
* @param p Velocity potentials.
* @param dp Acceleration potentials.
* @param waves Array of waves data (Amplitude,period,phase,heading)
* @param l Free surface length in the x direction.
* @param b Free surface length in the y direction.
* @param dx Distance between element centers in the x direction.
* @param dy Distance between element centers in the x direction.
* @param t Simulation time.
* @param nx Free surface points in the x direction.
* @param ny Free surface points in the y direction.
* @param nFS Number of points in the free surface.
* @param nB Number of points in the body (ignored yet, should be 0).
* @param n Total number of points.
* @param nSeax Number of repetitions of the free surface in the x direction.
* @param nSeay Number of repetitions of the free surface in the y direction.
* @param nW Number of waves.
*/
__kernel void matrixGen(__global float* A,
__global float* B,
__global float4* positions,
__global float* areas,
__global float4* normals,
__global float* p,
__global float* dp,
__global float4* waves,
float l,
float b,
float dx,
float dy,
float t,
unsigned int nx,
unsigned int ny,
unsigned int nFS,
unsigned int nB,
unsigned int n,
int nSeax,
int nSeay,
unsigned int nW)
{
// find position in global arrays
unsigned int i = get_global_id(0);
unsigned int j;
int I,J;
if(i >= n)
return;
// Get the point where we want to evaluate
float4 p_a = positions[i];
// Evaluate the row
B[i] = 0.f;
for(j=0;j<nFS;j++){
// Get G,H for this pair of points
float2 gh;
float4 p_b = positions[j];
float4 n_b = normals[j];
if(i == j){
gh = GH(positions,waves,normals,i/ny,i%ny,
l,b,dx,dy,t,nx,ny,nW);
}
else{
p_b = positions[j];
gh.x = G_val(p_b - p_a)*dx*dy;
gh.y = H_val(p_b - p_a, n_b)*dx*dy;
}
// In the free surface G goes to the linear system
// matrix while H goes to the B term
A[j + i*n] = -gh.x;
B[i] += gh.y * p[j];
// Compute also the terms of the virtual free surface
// extension.
for(I=-nSeax;I<=nSeax;I++){
for(J=-nSeay;J<=nSeay;J++){
if((!I) && (!J))
continue;
float4 p_c = p_b;
p_c.x += I*l;
p_c.y += J*b;
p_c.z = waves_z(waves, p_c, t, nW);
gh.x = G_val(p_c - p_a)*dx*dy;
gh.y = H_val(p_c - p_a, n_b)*dx*dy;
// In the extended free surface both terms goes to
// the B term
B[i] += gh.y*waves_phi(waves, p_c, t, nW) - gh.x*waves_gradphi(waves, p_c, t, nW);
}
}
}
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2011, 2012 *
* Jose Luis Cercos Pita <jlcercos@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License (LGPL) *
* as published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* for detail see the LICENCE text file. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this program; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
*/
/** Compute residuals of the solution stimator for a linear system.
* @param A Linear system matrix.
* @param B Linear system independent term.
* @param X Solution estimation.
* @param R Residuals.
* @param n Linear system dimension.
*/
__kernel void r(__global float* A,
__global float* B,
__global float* X,
__global float* R,
unsigned int n)
{
// find position in global arrays
unsigned int i = get_global_id(0);
unsigned int j;
if(i >= n)
return;
// Evaluate the row
R[i] = B[i];
for(j=0;j<n;j++){
R[i] -= A[j + i*n]*X[j];
}
}
/** Compute inner product between a matrix and a vector.
* @param A Matrix.
* @param X Vector.
* @param Y Result.
* @param n Linear system dimension.
*/
__kernel void dot_mat_vec(__global float* A,
__global float* X,
__global float* Y,
unsigned int n)
{
// find position in global arrays
unsigned int i = get_global_id(0);
unsigned int j;
if(i >= n)
return;
// Evaluate the row
Y[i] = 0.f;
for(j=0;j<n;j++){
Y[i] += A[j + i*n]*X[j];
}
}
/** Solve a linear system using Minimal residues iterative method.
* @param A Linear system matrix.
* @param r Residues vector.
* @param x0 Solution of the previous iteration.
* @param x Solution of the actual iteration.
* @param Ar_r dot(dot(A,r), r).
* @param Ar_Ar dot(dot(A,r), dot(A,r)).
* @param n Linear system dimension.
*/
__kernel void minres(__global float* A,
__global float* r,
__global float* x0,
__global float* x,
float Ar_r,
float Ar_Ar,
unsigned int n)
{
// find position in global arrays
unsigned int i = get_global_id(0);
if(i >= n)
return;
// Evaluate the row
x[i] = x0[i] + Ar_r / Ar_Ar * r[i];
}

View File

@ -49,9 +49,10 @@ class TaskPanel:
head = item.text().toFloat()[0]
w.append([A,T,phi,head])
obj = App.ActiveDocument.addObject("Part::FeaturePython","ShipSimulation")
sim = SimInstance.ShipSimulation(obj,
[form.length.value(), form.beam.value(), form.n.value()],
w)
sim = SimInstance.ShipSimulation(obj,
[form.fsL.value(), form.fsB.value(), form.fsNx.value(), form.fsNy.value()],
w,
form.error.value())
SimInstance.ViewProviderShipSimulation(obj.ViewObject)
return True
@ -80,21 +81,25 @@ class TaskPanel:
pass
def setupUi(self):
mw = self.getMainWindow()
form = mw.findChild(QtGui.QWidget, "TaskPanel")
form.length = form.findChild(QtGui.QDoubleSpinBox, "Length")
form.beam = form.findChild(QtGui.QDoubleSpinBox, "Beam")
form.n = form.findChild(QtGui.QSpinBox, "N")
form.waves = form.findChild(QtGui.QTableWidget, "Waves")
mw = self.getMainWindow()
form = mw.findChild(QtGui.QWidget, "TaskPanel")
form.fsL = form.findChild(QtGui.QDoubleSpinBox, "Length")
form.fsB = form.findChild(QtGui.QDoubleSpinBox, "Beam")
form.fsNx = form.findChild(QtGui.QSpinBox, "Nx")
form.fsNy = form.findChild(QtGui.QSpinBox, "Ny")
form.error = form.findChild(QtGui.QDoubleSpinBox, "Error")
form.waves = form.findChild(QtGui.QTableWidget, "Waves")
self.form = form
# Initial values
if self.initValues():
return True
self.retranslateUi()
# Connect Signals and Slots
QtCore.QObject.connect(form.length, QtCore.SIGNAL("valueChanged(double)"), self.onFS)
QtCore.QObject.connect(form.beam, QtCore.SIGNAL("valueChanged(double)"), self.onFS)
QtCore.QObject.connect(form.n, QtCore.SIGNAL("valueChanged(int)"), self.onFS)
QtCore.QObject.connect(form.fsL, QtCore.SIGNAL("valueChanged(double)"), self.onFS)
QtCore.QObject.connect(form.fsB, QtCore.SIGNAL("valueChanged(double)"), self.onFS)
QtCore.QObject.connect(form.fsNx, QtCore.SIGNAL("valueChanged(int)"), self.onFS)
QtCore.QObject.connect(form.fsNy, QtCore.SIGNAL("valueChanged(int)"), self.onFS)
QtCore.QObject.connect(form.error, QtCore.SIGNAL("valueChanged(double)"), self.onError)
QtCore.QObject.connect(form.waves,QtCore.SIGNAL("cellChanged(int,int)"),self.onWaves);
def getMainWindow(self):
@ -120,14 +125,12 @@ class TaskPanel:
None,QtGui.QApplication.UnicodeUTF8))
self.form.findChild(QtGui.QGroupBox, "FSDataBox").setTitle(QtGui.QApplication.translate("shipsim_create","Free surface",
None,QtGui.QApplication.UnicodeUTF8))
self.form.findChild(QtGui.QLabel, "LengthLabel").setText(QtGui.QApplication.translate("shipsim_create","Length",
None,QtGui.QApplication.UnicodeUTF8))
self.form.findChild(QtGui.QLabel, "BeamLabel").setText(QtGui.QApplication.translate("shipsim_create","Breadth",
None,QtGui.QApplication.UnicodeUTF8))
self.form.findChild(QtGui.QLabel, "NLabel").setText(QtGui.QApplication.translate("shipsim_create","Number of points",
None,QtGui.QApplication.UnicodeUTF8))
self.form.findChild(QtGui.QGroupBox, "WavesDataBox").setTitle(QtGui.QApplication.translate("shipsim_create","Waves",
None,QtGui.QApplication.UnicodeUTF8))
self.form.findChild(QtGui.QGroupBox, "OtherBox").setTitle(QtGui.QApplication.translate("shipsim_create","Other",
None,QtGui.QApplication.UnicodeUTF8))
self.form.findChild(QtGui.QLabel, "ErrorLabel").setText(QtGui.QApplication.translate("shipsim_create","Relative error",
None,QtGui.QApplication.UnicodeUTF8))
labels = []
labels.append(QtGui.QApplication.translate("shipsim_create","Amplitude",
None,QtGui.QApplication.UnicodeUTF8) + " [m]")
@ -138,6 +141,27 @@ class TaskPanel:
labels.append(QtGui.QApplication.translate("shipsim_create","Heading",
None,QtGui.QApplication.UnicodeUTF8) + " [deg]")
self.form.waves.setHorizontalHeaderLabels(labels)
# Set some tooltips
tooltip = QtGui.QApplication.translate("shipsim_create","Free surface length on x direction",
None,QtGui.QApplication.UnicodeUTF8)
self.form.findChild(QtGui.QLabel, "LengthLabel").setToolTip(tooltip)
self.form.findChild(QtGui.QDoubleSpinBox, "Length").setToolTip(tooltip)
tooltip = QtGui.QApplication.translate("shipsim_create","Free surface length on y direction",
None,QtGui.QApplication.UnicodeUTF8)
self.form.findChild(QtGui.QLabel, "BeamLabel").setToolTip(tooltip)
self.form.findChild(QtGui.QDoubleSpinBox, "Beam").setToolTip(tooltip)
tooltip = QtGui.QApplication.translate("shipsim_create","Number of nodes on x direction. Take into acount the following considerations:\n1.\tNodes must have an aspect ratio as near to 1,0 as possible, so this values must\n\taccomplish approximately that Nx/Ny = L/B\n3.\tThe linear system matrix generated will be of dimensions NxN, where\n\tN = Nx*Ny\n\tSo be mindful with the values selected and computer capabilities.",
None,QtGui.QApplication.UnicodeUTF8)
self.form.findChild(QtGui.QLabel, "NxLabel").setToolTip(tooltip)
self.form.findChild(QtGui.QSpinBox, "Nx").setToolTip(tooltip)
tooltip = QtGui.QApplication.translate("shipsim_create","Number of nodes on y direction. Take into acount the following considerations:\n1.\tNodes must have an aspect ratio as near to 1,0 as possible, so this values must\n\taccomplish approximately that Nx/Ny = L/B\n3.\tThe linear system matrix generated will be of dimensions NxN, where\n\tN = Nx*Ny\n\tSo be mindful with the values selected and computer capabilities.",
None,QtGui.QApplication.UnicodeUTF8)
self.form.findChild(QtGui.QLabel, "NyLabel").setToolTip(tooltip)
self.form.findChild(QtGui.QSpinBox, "Ny").setToolTip(tooltip)
tooltip = QtGui.QApplication.translate("shipsim_create","Relation between the minimum value of the Green's function (fartest point) and the maximum one.\nThis variable set the number of times that the Free surface will be virtually repeated.\nLower values may imply too much repeated free surfaces with a significant cost.",
None,QtGui.QApplication.UnicodeUTF8)
self.form.findChild(QtGui.QLabel, "ErrorLabel").setToolTip(tooltip)
self.form.findChild(QtGui.QDoubleSpinBox, "Error").setToolTip(tooltip)
def onFS(self, value):
""" Method called when free surface data is changed.
@ -145,6 +169,12 @@ class TaskPanel:
"""
pass
def onError(self, value):
""" Method called when sea data is changed.
@param value Changed value.
"""
pass
def onWaves(self, row, column):
""" Method called when waves data is changed.
@param row Affected row.

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>269</width>
<width>386</width>
<height>384</height>
</rect>
</property>
@ -42,7 +42,7 @@
<property name="minimumSize">
<size>
<width>0</width>
<height>128</height>
<height>0</height>
</size>
</property>
<property name="title">
@ -55,11 +55,11 @@
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
@ -78,15 +78,27 @@
<item>
<widget class="QLabel" name="LengthLabel">
<property name="text">
<string>Length</string>
<string>L</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="Length">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="maximum">
<double>1000000.000000000000000</double>
</property>
@ -98,37 +110,30 @@
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="BeamLabel">
<property name="text">
<string>Beam</string>
<string>B</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="Beam">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="maximum">
<double>1000000.000000000000000</double>
</property>
@ -160,22 +165,60 @@
<number>0</number>
</property>
<item>
<widget class="QLabel" name="NLabel">
<widget class="QLabel" name="NxLabel">
<property name="text">
<string>Number of points</string>
<string>Nx</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="N">
<widget class="QSpinBox" name="Nx">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="minimum">
<number>3</number>
</property>
<property name="maximum">
<number>10000000</number>
</property>
<property name="value">
<number>25</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="NyLabel">
<property name="text">
<string>Ny</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="Ny">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000000000</number>
<number>1000000</number>
</property>
<property name="value">
<number>1000</number>
<number>25</number>
</property>
</widget>
</item>
@ -260,6 +303,48 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="OtherBox">
<property name="title">
<string>Other</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="ErrorLabel">
<property name="text">
<string>Relative error</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="Error">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="decimals">
<number>4</number>
</property>
<property name="minimum">
<double>0.000100000000000</double>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.001000000000000</double>
</property>
<property name="value">
<double>0.001000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>

View File

@ -0,0 +1,55 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
# numpy
import numpy as np
import scipy.linalg as la
import FreeCAD
grav=9.81
class simBEMSolver:
def __init__(self, context=None, queue=None):
""" Constructor.
@param context OpenCL context where apply. Only for compatibility,
must be None.
@param queue OpenCL command queue. Only for compatibility,
must be None.
"""
self.context = context
self.queue = queue
def execute(self, bem):
""" Compute potential unknow data (gradients for free surface, and
potentials for the other ones).
@param bem Boundary Element Method instance.
"""
[bem['Ap'], residues, rank, s] = la.lstsq(bem['A'], bem['B'])
if(rank < bem['N']):
FreeCAD.Console.PrintError("\t\t[Sim]: Solving velocity potentials.\n")
FreeCAD.Console.PrintError("\t\t\tEffective rank of linear system matrix is %i (N = %i)\n" % (rank, bem['N']))
[bem['Adp'], residues, rank, s] = la.lstsq(bem['A'], bem['dB'])
if(rank < bem['N']):
FreeCAD.Console.PrintError("\t\t[Sim]: Solving acceleration potentials.\n")
FreeCAD.Console.PrintError("\t\t\tEffective rank of linear system matrix is %i (N = %i)\n" % (rank, bem['N']))

View File

@ -23,5 +23,5 @@
from initialization import *
from matrixGen import *
from computeSources import *
from fsEvolution import *
from BEMsolver import *
from evolution import *

View File

@ -0,0 +1,304 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
# numpy
import numpy as np
grav=9.81
class simEvolution:
def __init__(self, context=None, queue=None):
""" Constructor.
@param context OpenCL context where apply. Only for compatibility,
must be None.
@param queue OpenCL command queue. Only for compatibility,
must be None.
"""
self.context = context
self.queue = queue
def executeRK4(self, x, dx, p, dp, pos, vel, phi, dphi, fs, sea, body, waves, dt, t, stage):
""" Compute free surface RK4 stage evolution process (valid for stages 1,2 and 3).
@param x Output free surface z coordinates.
@param dx Output free surface z coordinates variation (dz/dt).
@param p Output potentials.
@param dp Output potentials variation (dphi/dt).
@param pos Input free surface positions.
@param vel Input free surface velocities.
@param phi Input potentials.
@param dphi Input potentials variation (dphi/dt).
@param fs Free surface instance.
@param sea Sea instance.
@param body Body instance.
@param waves Waves instance.
@param dt Time step.
@param t Actual time (without adding dt).
@param stage Runge-Kutta4 stage.
@return Input variables evoluted one time step.
"""
# --------------------------------------------
# Only free surface
# --------------------------------------------
h = fs['h']
nx = fs['Nx']
ny = fs['Ny']
nF = nx*ny
factor = 0.5
if stage > 2:
factor = 1.
for i in range(0,nx):
for j in range(0,ny):
x[i,j] = np.copy(pos[i,j][2])
dx[i,j] = np.copy(vel[i,j][2])
x[i,j] = x[i,j] + factor*dt*dx[i,j]
p[i*ny+j] = np.copy(phi[i*ny+j])
dp[i*ny+j] = np.copy(dphi[i*ny+j])
p[i*ny+j] = p[i*ny+j] + factor*dt*dp[i*ny+j]
# Impose values at beach (far free surface)
nbx = fs['Beachx']
nby = fs['Beachy']
for i in range(0,nx):
for j in range(0,nby) + range(ny-nby,ny):
[x[i,j],dx[i,j],p[i*ny+j],dp[i*ny+j]] = self.beach(pos[i,j], waves, factor*dt, t)
for j in range(0,ny):
for i in range(0,nbx) + range(nx-nbx,nx):
[x[i,j],dx[i,j],p[i*ny+j],dp[i*ny+j]] = self.beach(pos[i,j], waves, factor*dt, t)
# --------------------------------------------
# Sea boundaries, where potentials are fixed.
# We use the gradient projected over normal,
# see initialization for more details about
# this.
# --------------------------------------------
ids = ['front','back','left','right','bottom']
i0 = fs['N']
for index in ids:
s = sea[index]
nx = s['Nx']
ny = s['Ny']
for i in range(0,nx):
for j in range(0,ny):
p[i0 + i*ny+j] = 0.
dp[i0 + i*ny+j] = 0.
for w in waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
pos = s['pos'][i,j]
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
normal = s['normal'][i,j]
hfact = np.cosh(k*(pos[2]+h)) / np.cosh(k*h)
factor = np.dot(normal,np.array([np.cos(heading), np.sin(heading), 0.]))
amp = frec*A*np.sin(k*l - frec*(t+factor*dt) + phase)*hfact
p[i0 + i*ny+j] = p[i0 + i*ny+j] + factor*amp
amp = - grav*A*k*np.cos(k*l - frec*(t+factor*dt) + phase)*hfact
dp[i0 + i*ny+j] = dp[i0 + i*ny+j] + factor*amp
i0 = i0 + s['N']
def execute(self, dx1, dx2, dx3, dp1, dp2, dp3, fs, sea, body, waves, bem, dt, t):
""" Compute free surface evolution process (execute it on RK4 last stage).
@param dx1 Input free surface positions variation on stage 1.
@param dx2 Input free surface positions variation on stage 2.
@param dx3 Input free surface positions variation on stage 3.
@param dp1 Input free surface potentials variation on stage 1.
@param dp2 Input free surface potentials variation on stage 2.
@param dp3 Input free surface potentials variation on stage 3.
@param fs Free surface instance.
@param sea Sea instance.
@param body Body instance.
@param waves Waves instance.
@param bem Boundary Element Method instance.
@param dt Time step.
@param t Actual time (without adding dt).
@param stage Runge-Kutta4 stage.
@return Input variables evoluted one time step.
"""
h = fs['h']
nx = fs['Nx']
ny = fs['Ny']
nF = nx*ny
for i in range(0,nx):
for j in range(0,ny):
# In this stage dx4 and dp4 are directly known from the previous
# stage.
dx4 = fs['vel'][i,j][2]
dp4 = bem['dp4'][i*ny+j]
# And we only need to apply the integration scheme
fs['pos'][i,j][2] = fs['pos'][i,j][2] + dt/6. * (dx1[i,j] + 2.*dx2[i,j] + 2.*dx3[i,j] + dx4)
bem['p4'][i*ny+j] = bem['p4'][i*ny+j] + dt/6. * (dp1[i*ny+j] + 2.*dp2[i*ny+j] + 2.*dp3[i*ny+j] + dp4)
# In order to can apply the boundary condition at the free surface
# at the end of this RK4 stage, we need to store eta in a variable.
# x1 is safe because will be over written at the start of next
# time step.
fs['x1'][i,j] = fs['pos'][i,j][2]
# Impose values at beach (far free surface)
nbx = fs['Beachx']
nby = fs['Beachy']
for i in range(0,nx):
for j in range(0,nby) + range(ny-nby,ny):
[x,dummy,p,dummy] = self.beach(fs['pos'][i,j], waves, dt, t)
fs['pos'][i,j][2] = x
bem['p4'][i*ny+j] = p
fs['x1'][i,j] = fs['pos'][i,j][2]
for j in range(0,ny):
for i in range(0,nbx) + range(nx-nbx,nx):
[x,dummy,p,dummy] = self.beach(fs['pos'][i,j], waves, dt, t)
fs['pos'][i,j][2] = x
bem['p4'][i*ny+j] = p
fs['x1'][i,j] = fs['pos'][i,j][2]
# --------------------------------------------
# Sea boundaries, where potentials are fixed.
# We use the gradient projected over normal,
# see initialization for more details about
# this.
# --------------------------------------------
ids = ['front','back','left','right','bottom']
i0 = fs['N']
p = bem['p4']
dp = bem['dp4']
for index in ids:
s = sea[index]
nx = s['Nx']
ny = s['Ny']
for i in range(0,nx):
for j in range(0,ny):
p[i0 + i*ny+j] = 0.
dp[i0 + i*ny+j] = 0.
for w in waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
pos = s['pos'][i,j]
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
normal = s['normal'][i,j]
hfact = np.cosh(k*(pos[2]+h)) / np.cosh(k*h)
factor = np.dot(normal,np.array([np.cos(heading), np.sin(heading), 0.]))
amp = frec*A*np.sin(k*l - frec*(t+factor*dt) + phase)*hfact
p[i0 + i*ny+j] = p[i0 + i*ny+j] + factor*amp
amp = - grav*A*k*np.cos(k*l - frec*(t+factor*dt) + phase)*hfact
dp[i0 + i*ny+j] = dp[i0 + i*ny+j] + factor*amp
i0 = i0 + s['N']
def executeFSBC(self, x, fs, sea, body, waves, bem, dt, t, stage):
""" Compute free surface boundary conditions in order to get
free surface points velocity and potentials acceleration for
the next RK4 stage.
@param x Free surface z coordinates.
@param fs Free surface instance.
@param sea Sea boundaries instance.
@param body Body instance.
@param waves Waves instance.
@param bem Boundary Element Method instance.
@param dt Time step.
@param t Actual time (without adding dt).
"""
nx = fs['Nx']
ny = fs['Ny']
nF = nx*ny
factor = 0.5
if stage > 2:
factor = 1.
for i in range(0,nx):
for j in range(0,ny):
pos = np.copy(fs['pos'][i,j])
pos[2] = x[i,j]
gradVal = bem['Ap'][i*ny+j]
normal = fs['normal'][i,j]
# v_z = dphi/dz - grad(phi)*grad(z) - U*dz/dx
dzdt = gradVal*normal[2]
# dphi/dt = - rho*g*z - 0.5*grad(phi)^2 + v_z*dphi/dz - p_0 - U*dphi/dx - dU/dt*x
dphidt = -grav*pos[2] - 0.5*np.dot(gradVal,gradVal) # + dzdt*gradVal*normal[2]
# We need to preserve data on free surface global
# velocity and potential values in order to use as
# input of the next RK4 stage
fs['vel'][i,j][2] = dzdt
bem['dp4'][i*ny+j] = dphidt
# Impose values at beach (far free surface)
nbx = fs['Beachx']
nby = fs['Beachy']
for i in range(0,nx):
for j in range(0,nby) + range(ny-nby,ny):
[dummy,dx,dummy,dp] = self.beach(fs['pos'][i,j], waves, factor*dt, t)
fs['vel'][i,j][2] = dx
bem['dp4'][i*ny+j] = dp
for j in range(0,ny):
for i in range(0,nbx) + range(nx-nbx,nx):
[dummy,dx,dummy,dp] = self.beach(fs['pos'][i,j], waves, factor*dt, t)
fs['vel'][i,j][2] = dx
bem['dp4'][i*ny+j] = dp
def beach(self, pos, waves, dt, t):
""" Compute far free surface where only
incident waves can be taken into account.
@param pos Free surface position.
@param waves Waves instance.
@param dt Time step.
@param t Actual time (without adding dt).
@return Position, velocity, potential and potential acceleration
"""
h = waves['h']
x = 0.
dx = 0.
p = 0.
dp = 0.
# Since values of the potencial, and this acceleration,
# depends on z, we need to compute first the positions.
for w in waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
# hfact = np.sinh(k*(pos[2]+h)) / np.cosh(k*h)
hfact = 1.0
amp = A*np.sin(k*l - frec*(t+dt) + phase)*hfact
x = x + amp
amp = - A*frec*np.cos(k*l - frec*(t+dt) + phase)*hfact
dx = dx + amp
# And now we can compute potentials.
for w in waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
hfact = np.cosh(k*(x+h)) / np.cosh(k*h)
amp = - grav/frec*A*np.sin(k*l - frec*(t+dt) + phase)*hfact
p = p + amp
amp = grav*A*np.cos(k*l - frec*(t+dt) + phase)*hfact
dp = dp + amp
return [x,dx,p,dp]

View File

@ -1,119 +1,327 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#* USA *
#* *
#***************************************************************************
# numpy
import numpy as np
import FreeCAD
grav=9.81
class simInitialization:
def __init__(self, FSmesh, waves, context=None, queue=None):
""" Constructor.
@param FSmesh Initial free surface mesh.
@param waves Considered simulation waves (A,T,phi,heading).
@param context OpenCL context where apply. Only for compatibility,
must be None.
@param queue OpenCL command queue. Only for compatibility,
must be None.
"""
self.context = context
self.queue = queue
self.loadData(FSmesh, waves)
self.execute()
# Compute time step
self.dt = 0.1
for w in self.waves['data']:
if(self.dt > w[1]/200.0):
self.dt = w[1]/200.0
def __init__(self, h, FSMesh, SeaMesh, waves, context=None, queue=None):
""" Constructor.
@param h Water height.
@param FSMesh Initial free surface mesh.
@param waves Considered simulation waves (A,T,phi,heading).
@param context OpenCL context where apply. Only for compatibility,
must be None.
@param queue OpenCL command queue. Only for compatibility,
must be None.
"""
self.context = context
self.queue = queue
self.loadData(h, FSMesh, SeaMesh, waves)
self.execute()
# Compute time step
self.dt = 0.1
for w in self.waves['data']:
if(self.dt > w[1]/200.0):
self.dt = w[1]/200.0
def loadData(self, FSmesh, waves):
""" Convert data to numpy format.
@param FSmesh Initial free surface mesh.
@param waves Considered simulation waves (A,T,phi,heading).
"""
nx = len(FSmesh)
ny = len(FSmesh[0])
nW = len(waves)
# Mesh data
p = np.ndarray((nx,ny, 3), dtype=np.float32)
n = np.ndarray((nx,ny, 3), dtype=np.float32)
a = np.ndarray((nx,ny), dtype=np.float32)
phi = np.ndarray((nx,ny), dtype=np.float32)
Phi = np.ndarray((nx,ny), dtype=np.float32)
s = np.ndarray((nx,ny), dtype=np.float32)
ss = np.ndarray((nx,ny), dtype=np.float32)
for i in range(0, nx):
for j in range(0, ny):
pos = FSmesh[i][j].pos
normal = FSmesh[i][j].normal
area = FSmesh[i][j].area
p[i,j,0] = pos.x
p[i,j,1] = pos.y
p[i,j,2] = pos.z
n[i,j,0] = normal.x
n[i,j,1] = normal.y
n[i,j,2] = normal.z
a[i,j] = area
phi[i,j] = 0.
Phi[i,j] = 0.
s[i,j] = 0.
ss[i,j] = 0.
self.fs = {'Nx':nx, 'Ny':ny, 'pos':p, 'normal':n, 'area':a, \
'velPot':phi, 'accPot':Phi, 'velSrc':s, 'accSrc':ss}
# Waves data
w = np.ndarray((nW, 4), dtype=np.float32)
for i in range(0,nW):
w[i,0] = waves[i][0]
w[i,1] = waves[i][1]
w[i,2] = waves[i][2]
w[i,3] = waves[i][3]
self.waves = {'N':nW, 'data':w}
# Linear system matrix
nF = nx*ny
nB = 0 # No body for the moment
N = nx*ny + nB
self.A = np.ndarray((N, N), dtype=np.float32)
def loadData(self, h, FSMesh, SeaMesh, waves):
""" Convert data to numpy format.
@param FSMesh Initial free surface mesh.
@param waves Considered simulation waves (A,T,phi,heading).
"""
# Data will classified in four groups:
# Free surface:
# Is a key part of the simulation, so is
# separated from the rest of water involved
# elements.
# Sea:
# BEM method required a closed domain, so
# water floor and sides must be append, but
# are not a key objective of the simulation.
# Body:
# Is the main objective of the simulation.
# Waves:
# Data that is append as boundary condition.
# BEM:
# Used to solve the BEM problem and evolution.
# --------------------------------------------
# Free surface data
# N, Nx, Ny = Number of points in each
# direction
# pos = Positions
# vel = Velocities
# n = Normals
# area = Areas
# --------------------------------------------
nx = len(FSMesh)
ny = len(FSMesh[0])
p = np.ndarray((nx,ny, 3), dtype=np.float32)
V = np.zeros((nx,ny, 3), dtype=np.float32)
n = np.ndarray((nx,ny, 3), dtype=np.float32)
a = np.ndarray((nx,ny), dtype=np.float32)
x1 = np.zeros((nx,ny), dtype=np.float32)
x2 = np.zeros((nx,ny), dtype=np.float32)
x3 = np.zeros((nx,ny), dtype=np.float32)
dx1 = np.zeros((nx,ny), dtype=np.float32)
dx2 = np.zeros((nx,ny), dtype=np.float32)
dx3 = np.zeros((nx,ny), dtype=np.float32)
for i in range(0, nx):
for j in range(0, ny):
pos = FSMesh[i][j].pos
normal = FSMesh[i][j].normal
area = FSMesh[i][j].area
p[i,j,0] = pos.x
p[i,j,1] = pos.y
p[i,j,2] = pos.z
n[i,j,0] = normal.x
n[i,j,1] = normal.y
n[i,j,2] = normal.z
a[i,j] = area
self.fs = {'h': h, 'N':nx*ny, 'Nx':nx, 'Ny':ny, \
'pos':p, 'vel':V, 'normal':n, 'area':a, \
'x1':x1, 'x2':x2, 'x3':x3,\
'dx1':dx1, 'dx2':dx2, 'dx3':dx3}
# --------------------------------------------
# Sea data (dictionary with components
# ['front','back','left','right','bottom'])
# N, Nx, Ny = Number of points in each
# direction
# pos = Positions
# vel = Velocities
# n = Normals
# area = Areas
# --------------------------------------------
self.sea = {'ids':['front','back','left','right','bottom']}
N = 0
for index in self.sea['ids']:
mesh = SeaMesh[index]
nx = len(mesh)
ny = len(mesh[0])
p = np.ndarray((nx,ny, 3), dtype=np.float32)
V = np.zeros((nx,ny, 3), dtype=np.float32)
n = np.ndarray((nx,ny, 3), dtype=np.float32)
a = np.ndarray((nx,ny), dtype=np.float32)
for i in range(0, nx):
for j in range(0, ny):
pos = mesh[i][j].pos
normal = mesh[i][j].normal
area = mesh[i][j].area
p[i,j,0] = pos.x
p[i,j,1] = pos.y
p[i,j,2] = pos.z
n[i,j,0] = normal.x
n[i,j,1] = normal.y
n[i,j,2] = normal.z
a[i,j] = area
d = {'N':nx*ny, 'Nx':nx, 'Ny':ny, 'pos':p, 'vel':V, 'normal':n, 'area':a}
self.sea[index] = d
N = N + nx*ny
self.sea['N'] = N
self.sea['h'] = h
# --------------------------------------------
# Body data
# N, Nx, Ny = Number of points in each
# direction
# pos = Positions
# vel = Velocities
# n = Normals
# area = Areas
# --------------------------------------------
self.b = {'N':0, 'pos':None, 'vel':None, 'normal':None, 'area':None}
# --------------------------------------------
# Waves data
# N = Number of waves
# data = Waves data
# --------------------------------------------
nW = len(waves)
w = np.ndarray((nW, 4), dtype=np.float32)
for i in range(0,nW):
w[i,0] = waves[i][0]
w[i,1] = waves[i][1]
w[i,2] = waves[i][2]
w[i,3] = waves[i][3]
self.waves = {'h':h, 'N':nW, 'data':w}
# --------------------------------------------
# BEM data
# N = nFS + nSea + nB
# A,B,dB = Linear system matrix and vectors
# p1,... = Velocity potentials (phi) for
# each RK4 step. In reallity are
# the independent term of the
# BEM linear system, so is the
# potential for the free surface,
# and the gradient projected over
# the normal along all other terms.
# dp1,... = Acceleration potentials
# (dphi/dt) for each RK4 step.
# In reallity are the
# independent term of the BEM
# linear system, so is the
# potential for the free surface,
# and the gradient projected over
# the normal along all other terms.
# Ap,Adp = BEM solution vectors, that
# contains the potential gradients
# on free surface, and the potential
# along all toher surfaces.
# --------------------------------------------
nFS = self.fs['N']
nSea = self.sea['N']
nB = self.b['N']
N = nFS + nSea + nB
A = np.zeros((N, N), dtype=np.float32)
B = np.zeros((N), dtype=np.float32)
dB = np.zeros((N), dtype=np.float32)
p1 = np.zeros((N), dtype=np.float32)
p2 = np.zeros((N), dtype=np.float32)
p3 = np.zeros((N), dtype=np.float32)
p4 = np.zeros((N), dtype=np.float32)
Ap = np.zeros((N), dtype=np.float32)
dp1 = np.zeros((N), dtype=np.float32)
dp2 = np.zeros((N), dtype=np.float32)
dp3 = np.zeros((N), dtype=np.float32)
dp4 = np.zeros((N), dtype=np.float32)
Adp = np.zeros((N), dtype=np.float32)
self.bem = {'N':N, 'A':A, 'B':B, 'dB':dB, \
'p1':p1, 'p2':p2, 'p3':p3, 'p4':p4, 'Ap':Ap, \
'dp1':dp1, 'dp2':dp2, 'dp3':dp3, 'dp4':dp4, 'Adp':Adp }
def execute(self):
""" Compute initial conditions. """
# --------------------------------------------
# Free surface beach nodes.
# Beach nodes are the nodes of the free
# surface where the waves are imposed. All
# the other nodes are computed allowing non
# linear waves due to the ship interaction.
# The beach will have enough dimension to
# control at least half wave length
# --------------------------------------------
# Get maximum wave length
wl = 0.0
for w in self.waves['data']:
T = w[1]
wl = max(wl, 0.5 * grav / np.pi * T*T)
# Get nodes dimensions
nx = self.fs['Nx']
ny = self.fs['Ny']
lx = self.fs['pos'][nx-1,0][0] - self.fs['pos'][0,0][0]
ly = self.fs['pos'][0,ny-1][1] - self.fs['pos'][0,0][1]
dx = lx / nx
dy = ly / ny
# Get number of nodes involved
wnx = max(1, int(round(0.5*wl / dx)))
wny = max(1, int(round(0.5*wl / dy)))
wnx = min(wnx, nx)
wny = min(wny, ny)
self.fs['Beachx'] = wnx
self.fs['Beachy'] = wny
# --------------------------------------------
# Free surface initial condition.
# Since RK4 scheme starts on the end of
# previous step, we only write on last
# stage value (p4 and dp4)
# --------------------------------------------
nx = self.fs['Nx']
ny = self.fs['Ny']
h = self.fs['h']
for i in range(0,nx):
for j in range(0,ny):
# Since initial values of the potencial, and this acceleration,
# depends on z, we need to compute first the positions.
self.fs['pos'][i,j][2] = 0.
for w in self.waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
pos = self.fs['pos'][i,j]
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
# hfact = np.sinh(k*(pos[2]+h)) / np.cosh(k*h)
hfact = 1.0
amp = A*np.sin(k*l + phase)*hfact
self.fs['pos'][i,j][2] = self.fs['pos'][i,j][2] + amp
amp = - A*frec*np.cos(k*l + phase)*hfact
self.fs['vel'][i,j][2] = self.fs['vel'][i,j][2] + amp
# And now we can compute potentials.
for w in self.waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
pos = self.fs['pos'][i,j]
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
hfact = np.cosh(k*(pos[2]+h)) / np.cosh(k*h)
amp = - grav/frec*A*np.cos(k*l + phase)*hfact
self.bem['p4'][i*ny+j] = self.bem['p4'][i*ny+j] + amp
amp = - grav*A*np.sin(k*l + phase)*hfact
self.bem['dp4'][i*ny+j] = self.bem['dp4'][i*ny+j] + amp
# --------------------------------------------
# Sea initial condition on sides.
# 1. Since RK4 scheme starts on the end of
# previous step, we only write on last
# stage value (p4 and dp4)
# 2. In the sea boundaries we are
# interested on the gradient of the
# potentials projected over the normal,
# so we really store this value.
# 3. In the floor this value is ever null.
# --------------------------------------------
ids = ['front','back','left','right','bottom']
i0 = self.fs['N']
for index in ids:
sea = self.sea[index]
nx = sea['Nx']
ny = sea['Ny']
for i in range(0,nx):
for j in range(0,ny):
for w in self.waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
pos = sea['pos'][i,j]
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
normal = sea['normal'][i,j]
hfact = np.cosh(k*(pos[2]+h)) / np.cosh(k*h)
factor = np.dot(normal,np.array([np.cos(heading), np.sin(heading), 0.]))
amp = frec*A*np.sin(k*l + phase)*hfact
self.bem['p4'][i0 + i*ny+j] = self.bem['p4'][i*ny+j] + factor*amp
amp = - grav*A*k*np.cos(k*l + phase)*hfact
self.bem['dp4'][i0 + i*ny+j] = self.bem['dp4'][i*ny+j] + factor*amp
i0 = i0 + sea['N']
def execute(self):
""" Compute initial conditions. """
nx = self.fs['Nx']
ny = self.fs['Ny']
for i in range(0,nx):
for j in range(0,ny):
self.fs['pos'][i,j][2] = 0.
for w in self.waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
pos = self.fs['pos'][i,j]
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
amp = A*np.sin(k*l + phase)
self.fs['pos'][i,j][2] = self.fs['pos'][i,j][2] + amp
amp = - grav/frec*A*np.sin(k*l + phase)
self.fs['velPot'][i,j] = self.fs['velPot'][i,j] + amp
amp = grav*A*np.cos(k*l + phase)
self.fs['accPot'][i,j] = self.fs['accPot'][i,j] + amp

View File

@ -1,24 +1,24 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#* USA *
#* *
#***************************************************************************
# numpy
@ -27,53 +27,197 @@ import numpy as np
grav=9.81
class simMatrixGen:
def __init__(self, context=None, queue=None):
""" Constructor.
@param context OpenCL context where apply. Only for compatibility,
must be None.
@param queue OpenCL command queue. Only for compatibility,
must be None.
"""
self.context = context
self.queue = queue
def __init__(self, context=None, queue=None):
""" Constructor.
@param context OpenCL context where apply. Only for compatibility,
must be None.
@param queue OpenCL command queue. Only for compatibility,
must be None.
"""
self.context = context
self.queue = queue
def execute(self, fs, A):
""" Compute system matrix.
@param fs Free surface instance.
@param A Linear system matrix.
"""
self.fs = fs
nx = self.fs['Nx']
ny = self.fs['Ny']
nF = nx*ny
nB = 0 # No body for the moment
N = nx*ny + nB
# Fluid sources rows
for i in range(0,nx):
for j in range(0,ny):
# Append fluid effect
pos = self.fs['pos'][i,j]
A[i*ny+j,0:nF] = self.fluidEffect(pos)
# Append body effect
# ...
def execute(self, x, p, dp, fs, sea, bem, body):
""" Compute system matrix.
@param x Free surface z coordinates.
@param fs Free surface instance.
@param sea Sea boundary instance.
@param bem Boundary Element Method instance.
@param body Body instance.
"""
nFS = fs['N']
nSea = sea['N']
nB = body['N']
n = nFS + nSea + nB
A = bem['A']
B = bem['B']
dB = bem['dB']
# Free surface sources rows
nx = fs['Nx']
ny = fs['Ny']
for i in range(0,nx):
for j in range(0,ny):
pos = np.copy(fs['pos'][i,j])
pos[2] = x[i,j]
# Compute G terms
fsG = self.fsG(x, pos, fs)
seaG = self.seaG(pos, sea)
# Compute H terms
fsH = self.fsH(i*ny+j, x, pos, fs)
seaH = self.seaH(i*ny+j, pos, fs, sea)
# Append terms to linear system matrix
A[i*ny+j,0:nFS] = fsG
A[i*ny+j,nFS:n] = seaH
# Set independent terms
B[i*ny+j] = np.dot(fsH, p[0:nFS]) + np.dot(seaG, p[nFS:nFS+nSea])
dB[i*ny+j] = np.dot(fsH, dp[0:nFS]) + np.dot(seaG, dp[nFS:nFS+nSea])
# Append body effect
# ...
# Sea sources rows
ids = ['front','back','left','right','bottom']
count = 0
for index in ids:
s = sea[index]
nx = s['Nx']
ny = s['Ny']
for i in range(0,nx):
for j in range(0,ny):
pos = np.copy(s['pos'][i,j])
# Compute G terms
fsG = self.fsG(x, pos, fs)
seaG = self.seaG(pos, sea)
# Compute H terms
fsH = self.fsH(nFS+count, x, pos, fs)
seaH = self.seaH(nFS+count, pos, fs, sea)
# Append terms to linear system matrix
A[nFS+count, 0:nFS] = fsG
A[nFS+count, nFS:n] = seaH
# Set independent terms
B[nFS+count] = np.dot(fsH, p[0:nFS]) + np.dot(seaG, p[nFS:nFS+nSea])
dB[nFS+count] = np.dot(fsH, dp[0:nFS]) + np.dot(seaG, dp[nFS:nFS+nSea])
# Append body effect
# ...
count = count + 1
# Solid sources rows
# ...
def fsG(self, x, pos, fs):
r""" Compute free surface terms potential effect over desired position. Desingularized
sources must taken into account.
\$ G_{ij} = \sum_{j=0}^{n_{FS}-1} \log(\mathbf{r}_{ij}) \$
@param x Free surface z coordinates.
@param pos Point to evaluate.
@param fs Free surface instance.
@return Free surface effect row.
"""
nx = fs['Nx']
ny = fs['Ny']
nF = nx*ny
row = np.ndarray(nF, dtype=np.float32)
for i in range(0,nx):
for j in range(0,ny):
# Get source position (desingularized)
source = np.copy(fs['pos'][i,j])
source[2] = x[i,j]
area = fs['area'][i,j]
normal = fs['normal'][i,j]
source = source + np.sqrt(area)*normal
# Get union vector between points
r = pos-source
row[i*ny+j] = area * 0.5*np.log(np.dot(r,r))
return row
def fsH(self, index, x, pos, fs):
r""" Compute free surface terms potential gradient effect over desired position. Desingularized
sources must taken into account.
\$ H_{ij} = \sum_{j=0}^{n_{FS}-1} \frac{\mathbf{r}_{ij}}{\vert \mathbf{r}_{ij} \vert^2} \$
When the point effect over himself is considered, -1/2 must be append.
@param index Potential point index.
@param x Free surface z coordinates.
@param pos Point to evaluate.
@param fs Free surface instance.
@return Free surface effect row.
"""
nx = fs['Nx']
ny = fs['Ny']
nF = nx*ny
row = np.ndarray(nF, dtype=np.float32)
for i in range(0,nx):
for j in range(0,ny):
# Get source position (desingularized)
source = np.copy(fs['pos'][i,j])
source[2] = x[i,j]
area = fs['area'][i,j]
normal = fs['normal'][i,j]
source = source + np.sqrt(area)*normal
# Get union vector between points
r = pos-source
row[i*ny+j] = area * np.dot(r,normal) / np.dot(r,r)
# If effect over himslef is considered, apply the correction
if(index == i*ny+j):
row[i*ny+j] = row[i*ny+j] - 0.5
return row
def seaG(self, pos, sea):
r""" Compute sea boundary terms potential effect over desired position. Desingularized
sources must taken into account.
\$ G_{ij} = \sum_{j=0}^{n_{FS}-1} \log(\mathbf{r}_{ij}) \$
@param pos Point to evaluate.
@param sea Sea boundaries instance.
@return Sea boundaries effect row.
"""
ids = ['front','back','left','right','bottom']
count = 0
row = np.ndarray(sea['N'], dtype=np.float32)
for index in ids:
s = sea[index]
nx = s['Nx']
ny = s['Ny']
for i in range(0,nx):
for j in range(0,ny):
# Get source position (desingularized)
source = np.copy(s['pos'][i,j])
area = s['area'][i,j]
normal = s['normal'][i,j]
source = source + np.sqrt(area)*normal
# Get distance between points
r = pos-source
row[count] = area * 0.5*np.log(np.dot(r,r))
count = count + 1
return row
def seaH(self, index, pos, fs, sea):
r""" Compute sea boundary terms potential gradient effect over desired position. Desingularized
sources must taken into account.
\$ H_{ij} = \sum_{j=0}^{n_{FS}-1} \frac{\mathbf{r}_{ij}}{\vert \mathbf{r}_{ij} \vert^2} \$
When the point effect over himself is considered, -1/2 must be append.
@param index Potential point index.
@param pos Point to evaluate.
@param fs Free surface instance.
@param sea Sea boundaries instance.
@return Sea boundaries effect row.
"""
nF = fs['N']
ids = ['front','back','left','right','bottom']
count = 0
row = np.ndarray(sea['N'], dtype=np.float32)
for index in ids:
s = sea[index]
nx = s['Nx']
ny = s['Ny']
for i in range(0,nx):
for j in range(0,ny):
# Get source position (desingularized)
source = np.copy(s['pos'][i,j])
area = s['area'][i,j]
normal = s['normal'][i,j]
source = source + np.sqrt(area)*normal
# Get distance between points
r = pos-source
row[count] = area * np.dot(r,normal) / np.dot(r,r)
# If effect over himslef is considered, apply the correction
if(index == count+nF):
row[count] = row[count] - 0.5
count = count + 1
return row
def fluidEffect(self, pos):
""" Compute fluid effect terms over desired position. Desingularized
sources must taken into account.
@param pos Point to evaluate.
@return Fluid effect row.
"""
nx = self.fs['Nx']
ny = self.fs['Ny']
nF = nx*ny
row = np.ndarray(nF, dtype=np.float32)
for i in range(0,nx):
for j in range(0,ny):
# Get source position (desingularized)
source = np.copy(self.fs['pos'][i,j])
area = self.fs['area'][i,j]
source[2] = source[2] + np.sqrt(area)
# Get distance between points
d = np.linalg.norm(pos-source)
row[i*ny+j] = np.log(d)*area
return row

View File

@ -51,14 +51,17 @@ class Singleton(type):
class FreeCADShipSimulation(threading.Thread):
__metaclass__ = Singleton
def __init__ (self, device, endTime, output, simInstance, FSmesh, waves):
def __init__ (self, device, endTime, output, simInstance, FSMesh, FSData, waves, Sea_Nx, Sea_Ny):
""" Thread constructor.
@param device Device to use.
@param endTime Maximum simulation time.
@param output [Rate,Type] Output rate, Type=0 if FPS, 1 if IPF.
@param simInstance Simulaation instance.
@param FSmesh Free surface mesh faces.
@param FSMesh Free surface mesh faces.
@param FSData Free surface data (Length, Breath, Nx, Ny).
@param waves Waves parameters (A,T,phi,heading)
@param Sea_Nx Times that the free surface is virtually repeated in the x direction
@param Sea_Ny Times that the free surface is virtually repeated in the y direction
"""
threading.Thread.__init__(self)
# Setup as stopped
@ -75,9 +78,11 @@ class FreeCADShipSimulation(threading.Thread):
self.endTime = endTime
self.output = output
self.sim = simInstance
self.FSmesh = FSmesh
self.FSMesh = FSMesh
self.FSData = FSData
self.waves = waves
self.Sea = (Sea_Nx, Sea_Ny)
def run(self):
""" Runs the simulation.
"""
@ -90,36 +95,116 @@ class FreeCADShipSimulation(threading.Thread):
msg = QtGui.QApplication.translate("ship_console","Initializating",
None,QtGui.QApplication.UnicodeUTF8)
FreeCAD.Console.PrintMessage("\t[Sim]: " + msg + "...\n")
init = simInitialization(self.FSmesh,self.waves,self.context,self.queue)
matGen = simMatrixGen(self.context,self.queue)
solver = simComputeSources(self.context,self.queue)
fsEvol = simFSEvolution(self.context,self.queue)
A = init.A
FS = init.fs
waves = init.waves
dt = init.dt
if self.device == None: # Can't use OpenCL
init = simInitialization(self.FSMesh,self.FSData,self.waves,self.Sea,self.context,self.queue)
matGen = simMatrixGen(self.context,self.queue)
solver = simBEMSolver(self.context,self.queue)
evol = simEvolution(self.context,self.queue)
else:
init = simInitialization_cl(self.FSMesh,self.FSData,self.waves,self.Sea,self.context,self.queue)
matGen = simMatrixGen_cl(self.context,self.queue)
solver = simBEMSolver_cl(self.context,self.queue)
evol = simEvolution_cl(self.context,self.queue)
FS = init.fs
sea = init.sea
body = init.b
waves = init.waves
BEM = init.bem
dt = init.dt
self.t = 0.0
self.FS = FS
nx = FS['Nx']
ny = FS['Ny']
nx = FS['Nx']
ny = FS['Ny']
msg = QtGui.QApplication.translate("ship_console","Iterating",
None,QtGui.QApplication.UnicodeUTF8)
FreeCAD.Console.PrintMessage("\t[Sim]: " + msg + "...\n")
while self.active and self.t < self.endTime:
msg = QtGui.QApplication.translate("ship_console","Generating linear system matrix",
None,QtGui.QApplication.UnicodeUTF8)
FreeCAD.Console.PrintMessage("\t\t[Sim]: " + msg + "...\n")
matGen.execute(FS, A)
msg = QtGui.QApplication.translate("ship_console","Solving linear systems",
None,QtGui.QApplication.UnicodeUTF8)
FreeCAD.Console.PrintMessage("\t\t[Sim]: " + msg + "...\n")
solver.execute(FS, A)
msg = QtGui.QApplication.translate("ship_console","Time integrating",
None,QtGui.QApplication.UnicodeUTF8)
FreeCAD.Console.PrintMessage("\t\t[Sim]: " + msg + "...\n")
fsEvol.execute(FS, waves, dt, self.t)
# Simple Euler method
FreeCAD.Console.PrintMessage("\t\t\t[Sim]: Generating matrix...\n")
matGen.execute(FS, waves, sea, BEM, body, self.t)
FreeCAD.Console.PrintMessage("\t\t\t[Sim]: Solving linear system matrix...\n")
solver.execute(BEM)
FreeCAD.Console.PrintMessage("\t\t\t[Sim]: Integrating...\n")
# evol.execute(FS, BEM, waves, self.t, dt)
# --------------------------------------------------------
# Debugging
# --------------------------------------------------------
evol.BC(FS, BEM, waves, self.t)
f = open("%.4f.dat" % (self.t), 'w')
for i in range(0,FS['Nx']):
for j in range(0, FS['Ny']):
# Compute analitical solution
z = 0.0
vz = 0.0
p = 0.0
vp = 0.0
for w in waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
pos = FS['pos'][i,j]
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
amp = A*np.sin(k*l - frec*self.t + phase)
z = z + amp
amp = - A*frec*np.cos(k*l - frec*self.t + phase)
vz = vz + amp
for w in waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
pos = FS['pos'][i,j]
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
amp = - A*frec/k*np.cos(k*l - frec*self.t + phase)*np.exp(k*z)
p = p + amp
amp = - A*9.81*np.sin(k*l - frec*self.t + phase)*np.exp(k*z)
vp = vp + amp
"""
z = 0.
vz = 0.
p = 0.
vp = 0.
# We can do phi = Green's function
dx = FS['pos'][i,j][0]
dy = FS['pos'][i,j][1]
dz = 15.0 # An arbitrary value > 0
p = 1. / (4. * np.pi * np.sqrt(dx*dx + dy*dy + dz*dz))
vz = - dz / (4. * np.pi * (dx*dx + dy*dy + dz*dz)**(1.5))
"""
# write coordinates
f.write("%g %g " % (FS['pos'][i,j,0],FS['pos'][i,j,1]))
# write computed wave and velocity
f.write("%g %g " % (FS['pos'][i,j,2],FS['vel'][i,j,2]))
# write computed potential and time variation rate
# f.write("%g %g " % (BEM['p'][i*FS['Ny']+j],BEM['dpdt'][i*FS['Ny']+j]))
f.write("%g %g " % (BEM['p'][i*FS['Ny']+j],0.))
# write analytic wave and velocity
f.write("%g %g " % (z,vz))
# write analytic potential and time variation rate
# f.write("%g %g\n" % (p,vp))
f.write("%g %g\n" % (p,0.))
f.write("\n")
f.close()
evol.Integrate(FS, BEM, waves, self.t, dt)
# --------------------------------------------------------
# Debugging
# --------------------------------------------------------
self.t = self.t + dt
FreeCAD.Console.PrintMessage('\t[Sim]: t = %g s\n' % (self.t))
# Set thread as stopped (and prepare it to restarting)
self.active = False
threading.Event().set()

View File

@ -61,18 +61,22 @@ class TaskPanel:
device = d
count = count + 1
# Get free surfaces data
FSMesh = SimInstance.FSMesh(self.sim)
wData = self.sim.Waves
wDir = self.sim.Waves_Dir
waves = []
FSMesh = SimInstance.FSMesh(self.sim)
FSData = (self.sim.L,self.sim.B,self.sim.FS_Nx,self.sim.FS_Ny)
wData = self.sim.Waves
wDir = self.sim.Waves_Dir
waves = []
for i in range(0,len(wData)):
waves.append([wData[i].x, wData[i].y, wData[i].z, wDir[i]])
SeaNx = self.sim.Sea_Nx
SeaNy = self.sim.Sea_Ny
msg = QtGui.QApplication.translate("ship_console","Launching simulation",
None,QtGui.QApplication.UnicodeUTF8)
App.Console.PrintMessage(msg + "...\n")
# Build simulation thread
simulator = Sim(device, endTime, output, self.sim, FSMesh, waves)
simulator.start()
simulator = Sim(device, endTime, output, self.sim, FSMesh, FSData, waves, SeaNx, SeaNy)
simulator.start() # Activate me for final release
# simulator.run() # Activate me for development (i will show python fails)
msg = QtGui.QApplication.translate("ship_console","Done",
None,QtGui.QApplication.UnicodeUTF8)
App.Console.PrintMessage(msg + "!\n")

View File

@ -0,0 +1,61 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
# numpy
import numpy as np
from bem_jacobi_cl import jacobi
from bem_minres_cl import minres
from bem_lsqr_cl import lsqr
import FreeCAD
grav=9.81
class simBEMSolver_cl:
def __init__(self, context=None, queue=None):
""" Constructor.
@param context OpenCL context where apply.
@param queue OpenCL command queue.
"""
self.context = context
self.queue = queue
self.solver = lsqr(context, queue)
def execute(self, bem):
""" Compute potential unknow data (gradients for free surface, and
potentials for the other ones).
@param bem Boundary Element Method instance.
"""
"""
[bem['gradp'], r, iters] = self.solver.solve(bem['A'], bem['B'], bem['gradp'])
if(iters >= 300):
FreeCAD.Console.PrintError("\t\t[Sim]: Solving velocity potentials.\n")
FreeCAD.Console.PrintError("\t\t\tSolutions seems don't convergs after 300 iterations (%g residual)\n" % (r))
FreeCAD.Console.PrintMessage((r,iters))
FreeCAD.Console.PrintMessage("\n")
"""
import scipy.linalg as la
[bem['gradp'], residues, rank, s] = la.lstsq(bem['A'], bem['B'])
if(rank < bem['N']):
FreeCAD.Console.PrintError("\t\t[Sim]: Solving velocity potentials.\n")
FreeCAD.Console.PrintError("\t\t\tEffective rank of linear system matrix is {0} (N = {1})\n".format(rank, bem['N']))

View File

@ -21,4 +21,7 @@
#* *
#***************************************************************************
import initialization, Utils
from initialization import *
from matrixGen import *
from BEMsolver import *
from evolution import *

View File

@ -0,0 +1,155 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
# numpy
import numpy as np
# pyOpenCL
import pyopencl as cl
from pyopencl.reduction import ReductionKernel
import pyopencl.array as cl_array
import clUtils
import FreeCAD
grav=9.81
class jacobi:
def __init__(self, context, queue):
""" Constructor.
@param context OpenCL context where apply.
@param queue OpenCL command queue.
"""
self.context = context
self.queue = queue
self.program = clUtils.loadProgram(context, clUtils.path() + "/jacobi.cl")
# Create OpenCL objects as null objects, that we will generate
# at the first iteration
self.A = None
self.B = None
self.X0 = None
self.X = None
self.x = None
# Create dot operator
self.dot = ReductionKernel(context, np.float32, neutral="0",
reduce_expr="a+b", map_expr="x[i]*y[i]",
arguments="__global float *x, __global float *y")
def solve(self, A, B, x0=None, tol=10e-6, iters=300, w=1.0):
r""" Solve linear system of equations by a Jacobi
iterative method.
@param A Linear system matrix.
@param B Linear system independent term.
@param x0 Initial aproximation of the solution.
@param tol Relative error tolerance: \n
\$ \vert\vert B - A \, x \vert \vert_\infty /
\vert\vert B \vert \vert_\infty \$
@param iters Maximum number of iterations.
@param w Relaxation factor
"""
# Create/set OpenCL buffers
w = np.float32(w)
self.setBuffers(A,B,x0)
# Get dimensions for OpenCL execution
n = np.uint32(len(B))
gSize = (clUtils.globalSize(n),)
# Get a norm to can compare later for valid result
B_cl = cl_array.to_device(self.context,self.queue,B)
bnorm2 = self.dot(B_cl,B_cl).get()
w = w / bnorm2
FreeCAD.Console.PrintMessage(bnorm2)
FreeCAD.Console.PrintMessage("\n")
rnorm2 = 0.
# Iterate while the result converges or maximum number
# of iterations is reached.
for i in range(0,iters):
kernelargs = (self.A,
self.B,
self.X0,
self.X,
n)
# Test if the final result has been reached
self.program.r(self.queue, gSize, None, *(kernelargs))
cl.enqueue_read_buffer(self.queue, self.X, self.x).wait()
x_cl = cl_array.to_device(self.context,self.queue,self.x)
rnorm2 = self.dot(x_cl,x_cl).get()
FreeCAD.Console.PrintMessage("\t")
FreeCAD.Console.PrintMessage(rnorm2)
FreeCAD.Console.PrintMessage("\n")
if np.sqrt(rnorm2 / bnorm2) <= tol:
break
# Iterate
kernelargs = (self.A,
self.B,
self.X0,
self.X,
w,
n)
self.program.jacobi(self.queue, gSize, None, *(kernelargs))
kernelargs = (self.A,
self.B,
self.X,
self.X0,
w,
n)
self.program.jacobi(self.queue, gSize, None, *(kernelargs))
# Return result computed
cl.enqueue_read_buffer(self.queue, self.X0, self.x).wait()
return (np.copy(self.x), np.sqrt(rnorm2 / bnorm2), i)
def setBuffers(self, A,B,x0):
""" Create/set OpenCL required buffers.
@param A Linear system matrix.
@param B Independent linear term.
@param x0 Initial solution estimator.
"""
# Get dimensions
shape = np.shape(A)
if len(shape) != 2:
raise ValueError, 'Matrix A must be 2 dimensional array'
if shape[0] != shape[1]:
raise ValueError, 'Square linear system matrix expected'
if len(B) != shape[0]:
raise ValueError, 'Matrix and independet term dimensions does not match'
n = len(B)
# Set x0 if not provided
if x0 != None:
if len(x0) != n:
raise ValueError, 'Initial solution estimator length does not match with linear system dimensions'
if x0 == None:
x0 = B
# Create OpenCL objects if not already generated
if not self.A:
mf = cl.mem_flags
self.A = cl.Buffer( self.context, mf.READ_ONLY, size = n*n * np.dtype('float32').itemsize )
self.B = cl.Buffer( self.context, mf.READ_ONLY, size = n * np.dtype('float32').itemsize )
self.X0 = cl.Buffer( self.context, mf.READ_WRITE, size = n * np.dtype('float32').itemsize )
self.X = cl.Buffer( self.context, mf.READ_WRITE, size = n * np.dtype('float32').itemsize )
self.x = np.zeros((n), dtype=np.float32)
# Transfer data to buffers
events = []
events.append(cl.enqueue_write_buffer(self.queue, self.A, A.reshape((n*n)) ))
events.append(cl.enqueue_write_buffer(self.queue, self.B, B))
events.append(cl.enqueue_write_buffer(self.queue, self.X0, x0))
for e in events:
e.wait()

View File

@ -0,0 +1,229 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
# numpy
import numpy as np
# pyOpenCL
import pyopencl as cl
from pyopencl.reduction import ReductionKernel
from pyopencl.elementwise import ElementwiseKernel
import pyopencl.array as cl_array
import clUtils
import FreeCAD
grav=9.81
class lsqr:
def __init__(self, context, queue):
""" Constructor.
@param context OpenCL context where apply.
@param queue OpenCL command queue.
"""
self.context = context
self.queue = queue
self.program = clUtils.loadProgram(context, clUtils.path() + "/lsqr.cl")
# Create OpenCL objects as null objects, that we will generate
# at the first iteration
self.A = None
self.B = None
self.X0 = None
self.X = None
self.R = None
# Create dot operator
self.dot = ReductionKernel(context, np.float32, neutral="0",
reduce_expr="a+b", map_expr="x[i]*y[i]",
arguments="__global float *x, __global float *y")
self.dot_c_vec = ElementwiseKernel(context,
"float c, float *v",
"v[i] *= c")
self.copy_vec = ElementwiseKernel(context,
"float* out, float *in",
"out[i] = in[i]")
self.linear_comb = ElementwiseKernel(context,
"float* z,"
"float a, float *x, "
"float b, float *y",
"z[i] = a*x[i] + b*y[i]")
self.prod = ElementwiseKernel(context,
"float* z,"
"float *x, float *y",
"z[i] = x[i]*y[i]")
def solve(self, A, B, x0=None, tol=10e-6, iters=300):
r""" Solve linear system of equations by a Jacobi
iterative method.
@param A Linear system matrix.
@param B Linear system independent term.
@param x0 Initial aproximation of the solution.
@param tol Relative error tolerance: \n
\$ \vert\vert B - A \, x \vert \vert_\infty /
\vert\vert B \vert \vert_\infty \$
@param iters Maximum number of iterations.
"""
# Create/set OpenCL buffers
self.setBuffers(A,B,x0)
# Get dimensions for OpenCL execution
n = np.uint32(len(B))
gSize = (clUtils.globalSize(n),)
# Preconditionate matrix
self.precondition(n)
# Get a norm to can compare later for valid result
bnorm = np.sqrt(self.dot(self.b,self.b).get())
FreeCAD.Console.PrintMessage(bnorm)
FreeCAD.Console.PrintMessage("\n")
# Initialize the problem
beta = bnorm
self.dot_c_vec(1.0/beta, self.u)
kernelargs = (self.A,self.u.data,self.v.data,n)
self.program.dot_matT_vec(self.queue, gSize, None, *(kernelargs))
alpha = np.sqrt(self.dot(self.v,self.v).get())
self.dot_c_vec(1.0/alpha, self.v)
self.copy_vec(self.w, self.v)
rhobar = alpha
phibar = beta
# Iterate while the result converges or maximum number
# of iterations is reached.
for i in range(0,iters):
# Compute residues
kernelargs = (self.A,
self.b.data,
self.x.data,
self.r.data,
n)
self.program.r(self.queue, gSize, None, *(kernelargs))
rnorm = np.sqrt(self.dot(self.r,self.r).get())
FreeCAD.Console.PrintMessage("\t")
FreeCAD.Console.PrintMessage(rnorm)
FreeCAD.Console.PrintMessage("\n")
# Test if the final result has been reached
if rnorm / bnorm <= tol:
break
# Compute next alpha, beta, u, v
kernelargs = (self.A,self.u.data,self.v.data,self.u.data,alpha,n)
self.program.u(self.queue, gSize, None, *(kernelargs))
beta = np.sqrt(self.dot(self.u,self.u).get())
FreeCAD.Console.PrintMessage("\t beta=")
FreeCAD.Console.PrintMessage(beta)
FreeCAD.Console.PrintMessage("\n")
self.dot_c_vec(1.0/beta, self.u)
kernelargs = (self.A,self.u.data,self.v.data,self.v.data,beta,n)
self.program.v(self.queue, gSize, None, *(kernelargs))
alpha = np.sqrt(self.dot(self.v,self.v).get())
FreeCAD.Console.PrintMessage("\t alpha=")
FreeCAD.Console.PrintMessage(alpha)
FreeCAD.Console.PrintMessage("\n")
self.dot_c_vec(1.0/alpha, self.v)
# Apply the orthogonal transformation
rho = np.sqrt(rhobar*rhobar + beta*beta)
c = rhobar/rho
s = beta*rho
theta = s*alpha
rhobar = -c*alpha
phi = c*phibar
phibar = s*phibar
# Update x and w
self.linear_comb(self.x, 1, self.x, phi/rho, self.w)
self.linear_comb(self.w, 1, self.v, theta/rho, self.w)
# Correct returned result due to the precoditioning
self.prod(self.x, self.xf, self.x)
# Return result computed
x = np.zeros((n), dtype=np.float32)
cl.enqueue_read_buffer(self.queue, self.x.data, x).wait()
return (x, rnorm / bnorm, i)
def setBuffers(self, A,B,x0):
""" Create/set OpenCL required buffers.
@param A Linear system matrix.
@param B Independent linear term.
@param x0 Initial solution estimator.
"""
# Get dimensions
shape = np.shape(A)
if len(shape) != 2:
raise ValueError, 'Matrix A must be 2 dimensional array'
if shape[0] != shape[1]:
raise ValueError, 'Square linear system matrix expected'
if len(B) != shape[0]:
raise ValueError, 'Matrix and independet term dimensions does not match'
n = len(B)
# Set x0 if not provided
if x0 != None:
if len(x0) != n:
raise ValueError, 'Initial solution estimator length does not match with linear system dimensions'
if x0 == None:
x0 = B
# Create OpenCL objects if not already generated
if not self.A:
mf = cl.mem_flags
self.A = cl.Buffer( self.context, mf.READ_WRITE, size = n*n * np.dtype('float32').itemsize )
self.b = cl_array.zeros(self.context,self.queue, (n), np.float32)
self.x = cl_array.zeros(self.context,self.queue, (n), np.float32)
self.xf = cl_array.zeros(self.context,self.queue, (n), np.float32)
self.r = cl_array.zeros(self.context,self.queue, (n), np.float32)
self.u = cl_array.zeros(self.context,self.queue, (n), np.float32)
self.v = cl_array.zeros(self.context,self.queue, (n), np.float32)
self.w = cl_array.zeros(self.context,self.queue, (n), np.float32)
# Transfer data to buffers
events = []
events.append(cl.enqueue_write_buffer(self.queue, self.A, A.reshape((n*n)) ))
self.b.set(B)
self.x.set(x0)
self.u.set(B)
for e in events:
e.wait()
def precondition(self, n):
""" Preconditionate matrix, ensuring that all linear system
matrix columns has an acceptable norm. Of course, final
solution vector must be corrected conveniently.
@param n Linear system dimension.
"""
gSize = (clUtils.globalSize(n),)
xf = np.ones((n), dtype=np.float32)
for i in range(0,n):
col = np.uint32(i)
# Compute column norm
# We can use v as column vector because has not been used yet
kernelargs = (self.A,
self.v.data,
col,
n)
self.program.column(self.queue, gSize, None, *(kernelargs))
norm = np.sqrt(self.dot(self.v,self.v).get())
FreeCAD.Console.PrintMessage("col ")
FreeCAD.Console.PrintMessage(i)
FreeCAD.Console.PrintMessage(", norm=")
FreeCAD.Console.PrintMessage(norm)
FreeCAD.Console.PrintMessage("\n")
if norm < 1.0:
continue
fact = np.float32(1.0/norm)
xf[i] = fact
kernelargs = (self.A,
fact,
col,
n)
self.program.prod_c_column(self.queue, gSize, None, *(kernelargs))
self.x.set(xf)

View File

@ -0,0 +1,157 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
# numpy
import numpy as np
# pyOpenCL
import pyopencl as cl
from pyopencl.reduction import ReductionKernel
import pyopencl.array as cl_array
import clUtils
import FreeCAD
grav=9.81
class minres:
def __init__(self, context, queue):
""" Constructor.
@param context OpenCL context where apply.
@param queue OpenCL command queue.
"""
self.context = context
self.queue = queue
self.program = clUtils.loadProgram(context, clUtils.path() + "/minres.cl")
# Create OpenCL objects as null objects, that we will generate
# at the first iteration
self.A = None
self.B = None
self.X0 = None
self.X = None
self.R = None
# Create dot operator
self.dot = ReductionKernel(context, np.float32, neutral="0",
reduce_expr="a+b", map_expr="x[i]*y[i]",
arguments="__global float *x, __global float *y")
def solve(self, A, B, x0=None, tol=10e-6, iters=300):
r""" Solve linear system of equations by a Jacobi
iterative method.
@param A Linear system matrix.
@param B Linear system independent term.
@param x0 Initial aproximation of the solution.
@param tol Relative error tolerance: \n
\$ \vert\vert B - A \, x \vert \vert_\infty /
\vert\vert B \vert \vert_\infty \$
@param iters Maximum number of iterations.
"""
# Create/set OpenCL buffers
self.setBuffers(A,B,x0)
# Get dimensions for OpenCL execution
n = np.uint32(len(B))
gSize = (clUtils.globalSize(n),)
# Get a norm to can compare later for valid result
B_cl = cl_array.to_device(self.context,self.queue,B)
bnorm2 = self.dot(B_cl,B_cl).get()
FreeCAD.Console.PrintMessage(bnorm2)
FreeCAD.Console.PrintMessage("\n")
# Iterate while the result converges or maximum number
# of iterations is reached.
for i in range(0,iters):
# Compute residues
kernelargs = (self.A,
self.B,
self.X0,
self.R.data,
n)
# Test if the final result has been reached
self.program.r(self.queue, gSize, None, *(kernelargs))
rnorm2 = self.dot(self.R,self.R).get()
FreeCAD.Console.PrintMessage("\t")
FreeCAD.Console.PrintMessage(rnorm2)
FreeCAD.Console.PrintMessage("\n")
if np.sqrt(rnorm2 / bnorm2) <= tol:
break
# Iterate
kernelargs = (self.A,
self.R.data,
self.AR.data,
n)
self.program.dot_mat_vec(self.queue, gSize, None, *(kernelargs))
AR_R = self.dot(self.AR,self.R).get()
AR_AR = self.dot(self.AR,self.AR).get()
kernelargs = (self.A,
self.R.data,
self.X,
self.X0,
AR_R,
AR_AR,
n)
self.program.minres(self.queue, gSize, None, *(kernelargs))
# Swap variables
swap = self.X
self.X = self.X0
self.X0 = swap
# Return result computed
x = np.zeros((n), dtype=np.float32)
cl.enqueue_read_buffer(self.queue, self.X0, x).wait()
return (x, np.sqrt(rnorm2 / bnorm2), i)
def setBuffers(self, A,B,x0):
""" Create/set OpenCL required buffers.
@param A Linear system matrix.
@param B Independent linear term.
@param x0 Initial solution estimator.
"""
# Get dimensions
shape = np.shape(A)
if len(shape) != 2:
raise ValueError, 'Matrix A must be 2 dimensional array'
if shape[0] != shape[1]:
raise ValueError, 'Square linear system matrix expected'
if len(B) != shape[0]:
raise ValueError, 'Matrix and independet term dimensions does not match'
n = len(B)
# Set x0 if not provided
if x0 != None:
if len(x0) != n:
raise ValueError, 'Initial solution estimator length does not match with linear system dimensions'
if x0 == None:
x0 = B
# Create OpenCL objects if not already generated
if not self.A:
mf = cl.mem_flags
self.A = cl.Buffer( self.context, mf.READ_ONLY, size = n*n * np.dtype('float32').itemsize )
self.B = cl.Buffer( self.context, mf.READ_ONLY, size = n * np.dtype('float32').itemsize )
self.X0 = cl.Buffer( self.context, mf.READ_WRITE, size = n * np.dtype('float32').itemsize )
self.X = cl.Buffer( self.context, mf.READ_WRITE, size = n * np.dtype('float32').itemsize )
self.R = cl_array.zeros(self.context,self.queue, (n), np.float32)
self.AR = cl_array.zeros(self.context,self.queue, (n), np.float32)
# Transfer data to buffers
events = []
events.append(cl.enqueue_write_buffer(self.queue, self.A, A.reshape((n*n)) ))
events.append(cl.enqueue_write_buffer(self.queue, self.B, B))
events.append(cl.enqueue_write_buffer(self.queue, self.X0, x0))
for e in events:
e.wait()

View File

@ -0,0 +1,58 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
# FreeCAD
from shipUtils import Paths
# pyOpenCL
import pyopencl as cl
import numpy as np
# Standard
import math
def loadProgram(context, file):
""" Loads a file and comnpile it.
@param context OpenCL context where apply.
@param file File to load and compile.
@return Ready to use OpenCL program.
"""
f = open(file, 'r')
str = "".join(f.readlines())
return cl.Program(context, str).build()
def path():
""" Gets the OpenCL kernels path
@return OpenCL kernels path
"""
path = Paths.modulePath() + "/resources/opencl"
return path
def globalSize(n):
""" Compute global size from amount of data.
@param n Amount of data.
@return global size.
"""
localSize = 256.0
return int(math.ceil(n/localSize)*localSize)

View File

@ -0,0 +1,258 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
# numpy
import numpy as np
import FreeCAD
grav=9.81
class simEvolution_cl:
def __init__(self, context=None, queue=None):
""" Constructor.
@param context OpenCL context where apply. Only for compatibility,
must be None.
@param queue OpenCL command queue. Only for compatibility,
must be None.
"""
self.context = context
self.queue = queue
def execute(self, fs, bem, waves, t, dt):
""" Compute the variables unknow for the next time step.
@param fs Free surface instance.
@param bem Boundary elements method instance.
@param waves Waves instance.
@param t Simulation time.
@param dt Time step.
"""
self.BC(fs,bem,waves, t)
self.Integrate(fs,bem,waves, t,dt)
def BC(self, fs, bem, waves, t):
""" Apply the boundary conditions to compute time variation rate
of the unknow variables.
@param fs Free surface instance.
@param bem Boundary elements method instance.
@param waves Waves instance.
@param t Simulation time.
"""
nx = fs['Nx']
ny = fs['Ny']
nFS = nx*ny
for i in range(0,nx):
for j in range(0,ny):
gradp = np.copy(bem['gradp'][i*ny+j])
z = fs['pos'][i,j,2]
bem['dpdt'][i*ny+j] = - 0.5 * gradp**2.0 - 9.81*z
fs['vel'][i,j,2] = gradp
# Since the inverse method returns significant errors near
# to the free surface borders, we will modify 3 area
# elements of the border such that the last one will be
# exactly the analytic solution. Also we will use it as
# numerical beach in order to disipate waves generated
# inside the domain (that will be refelceted otherwise)
# 1.- Corners
for i in range(0,4)+range(nx-4,nx):
if i in range(0,4):
fx = 1. - i/4.
else:
fx = (i - nx + 5) / 4.
for j in range(0,4)+range(ny-4,ny):
if j in range(0,4):
fy = 1. - j/4.
else:
fy = (j - ny + 5) / 4.
factor = max(fx,fy)
pos = fs['pos'][i,j]
dpdt = 0.
vel = 0.
for w in waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
amp = - A*9.81*np.sin(k*l - frec*t + phase)*np.exp(k*pos[2])
dpdt = dpdt + amp
amp = - A*frec*np.cos(k*l - frec*t + phase)
vel = vel + amp
bem['dpdt'][i*ny+j] = factor*dpdt + (1.-factor)*bem['dpdt'][i*ny+j]
fs['vel'][i,j,2] = factor*vel + (1.-factor)*fs['vel'][i,j,2]
# 2.- rows
for i in range(0,4)+range(nx-4,nx):
if i in range(0,4):
factor = 1. - i/4.
else:
factor = (i - nx + 5) / 4.
for j in range(4, ny-4):
pos = fs['pos'][i,j]
dpdt = 0.
vel = 0.
for w in waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
amp = - A*9.81*np.sin(k*l - frec*t + phase)*np.exp(k*pos[2])
dpdt = dpdt + amp
amp = - A*frec*np.cos(k*l - frec*t + phase)
vel = vel + amp
bem['dpdt'][i*ny+j] = factor*dpdt + (1.-factor)*bem['dpdt'][i*ny+j]
fs['vel'][i,j,2] = factor*vel + (1.-factor)*fs['vel'][i,j,2]
# 3.- columns
for j in range(0,4)+range(ny-4,ny):
if j in range(0,4):
factor = 1. - j/4.
else:
factor = (j - ny + 5) / 4.
for i in range(4, nx-4):
pos = fs['pos'][i,j]
dpdt = 0.
vel = 0.
for w in waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
amp = - A*9.81*np.sin(k*l - frec*t + phase)*np.exp(k*pos[2])
dpdt = dpdt + amp
amp = - A*frec*np.cos(k*l - frec*t + phase)
vel = vel + amp
bem['dpdt'][i*ny+j] = factor*dpdt + (1.-factor)*bem['dpdt'][i*ny+j]
fs['vel'][i,j,2] = factor*vel + (1.-factor)*fs['vel'][i,j,2]
def Integrate(self, fs, bem, waves, t, dt):
""" Perform time integration of the unknow variables.
@param fs Free surface instance.
@param bem Boundary elements method instance.
@param waves Waves instance.
@param t Simulation time.
@param dt Time step.
"""
nx = fs['Nx']
ny = fs['Ny']
nFS = nx*ny
for i in range(0,nx):
for j in range(0,ny):
bem['p'][i*ny+j] = bem['p'][i*ny+j] + dt * bem['dpdt'][i*ny+j]
fs['pos'][i,j,2] = fs['pos'][i,j,2] + dt * fs['vel'][i,j,2]
# Since the inverse method returns significant errors near
# to the free surface borders, we will modify 3 area
# elements of the border such that the last one will be
# exactly the analytic solution. Also we will use it as
# numerical beach in order to disipate waves generated
# inside the domain (that will be refelceted otherwise)
# 1.- Corners
for i in range(0,4)+range(nx-4,nx):
if i in range(0,4):
fx = 1. - i/4.
else:
fx = (i - nx + 5) / 4.
for j in range(0,4)+range(ny-4,ny):
if j in range(0,4):
fy = 1. - j/4.
else:
fy = (j - ny + 5) / 4.
factor = max(fx,fy)
pos = fs['pos'][i,j]
phi = 0.
z = 0.
for w in waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
amp = - A*frec/k*np.cos(k*l - frec*(t+dt) + phase)*np.exp(k*pos[2])
phi = phi + amp
amp = A*np.sin(k*l - frec*(t+dt) + phase)
z = z + amp
bem['p'][i*ny+j] = factor*phi + (1.-factor)*bem['p'][i*ny+j]
fs['pos'][i,j,2] = factor*z + (1.-factor)*fs['pos'][i,j,2]
# 2.- rows
for i in range(0,4)+range(nx-4,nx):
if i in range(0,4):
factor = 1. - i/4.
else:
factor = (i - nx + 5) / 4.
for j in range(4, ny-4):
pos = fs['pos'][i,j]
phi = 0.
z = 0.
for w in waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
amp = - A*frec/k*np.cos(k*l - frec*(t+dt) + phase)*np.exp(k*pos[2])
phi = phi + amp
amp = A*np.sin(k*l - frec*(t+dt) + phase)
z = z + amp
bem['p'][i*ny+j] = factor*phi + (1.-factor)*bem['p'][i*ny+j]
fs['pos'][i,j,2] = factor*z + (1.-factor)*fs['pos'][i,j,2]
# 3.- columns
for j in range(0,4)+range(ny-4,ny):
if j in range(0,4):
factor = 1. - j/4.
else:
factor = (j - ny + 5) / 4.
for i in range(4, nx-4):
pos = fs['pos'][i,j]
phi = 0.
z = 0.
for w in waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
amp = - A*frec/k*np.cos(k*l - frec*(t+dt) + phase)*np.exp(k*pos[2])
phi = phi + amp
amp = A*np.sin(k*l - frec*(t+dt) + phase)
z = z + amp
bem['p'][i*ny+j] = factor*phi + (1.-factor)*bem['p'][i*ny+j]
fs['pos'][i,j,2] = factor*z + (1.-factor)*fs['pos'][i,j,2]

View File

@ -1,113 +1,229 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#* USA *
#* *
#***************************************************************************
# Simulation stuff
from Utils import *
# pyOpenCL
import pyopencl as cl
# numpy
import numpy as np
import FreeCAD
class perform:
def __init__(self, FSmesh, waves, context, queue):
""" Constructor, includes program loading.
@param FSmesh Initial free surface mesh.
@param waves Considered simulation waves (A,T,phi,heading).
@param context OpenCL context where apply.
@param queue OpenCL command queue.
"""
self.context = context
self.queue = queue
self.program = loadProgram(context, clPath() + "/simInit.cl")
self.loadData(FSmesh, waves)
self.execute()
grav=9.81
class simInitialization_cl:
def __init__(self, FSMesh, FSData, waves, Sea, context=None, queue=None):
""" Constructor.
@param FSMesh Initial free surface mesh.
@param FSData Dimensions data of the free surface mesh (L,B,Nx,Ny)
@param waves Considered simulation waves (A,T,phi,heading).
@param Sea Tuple with the number of free surfaces that must be repeated in each direction.
@param context OpenCL context where apply. Only for compatibility,
must be None.
@param queue OpenCL command queue. Only for compatibility,
must be None.
"""
self.context = context
self.queue = queue
self.loadData(FSMesh, FSData, waves, Sea)
self.execute()
# Compute time step
self.dt = 0.1
for w in self.waves['data']:
if(self.dt > w[1]/200.0):
self.dt = w[1]/200.0
def loadData(self, FSMesh, FSData, waves, Sea):
""" Convert data to numpy format.
@param FSMesh Initial free surface mesh.
@param FSData Dimensions data of the free surface mesh (L,B,Nx,Ny)
@param waves Considered simulation waves (A,T,phi,heading).
@param Sea Tuple with the number of free surfaces that must be repeated in each direction.
"""
# Data will classified in four groups:
# Free surface:
# Is a key part of the simulation, so is
# separated from the rest of water involved
# elements.
# Sea:
# BEM method requires to artificially extend
# the free surface in order to send the bounds
# Inlet, Outlet, Left and Side to the infinite.
# Here is specified how many time must be
# repeated the free surface in order to get
# virtually infinite far bounds.
# Body:
# Is the main objective of the simulation.
# Waves:
# Data that is append as boundary condition.
# BEM:
# Used to solve the BEM problem and evolution.
# --------------------------------------------
# Free surface data
# N, Nx, Ny = Number of points in each
# direction
# pos = Positions
# vel = Velocities
# n = Normals
# area = Areas
# --------------------------------------------
nx = len(FSMesh)
ny = len(FSMesh[0])
L = FSData[0]
B = FSData[1]
dx = L/nx
dy = B/ny
p = np.zeros((nx,ny, 4), dtype=np.float32)
V = np.zeros((nx,ny, 4), dtype=np.float32)
n = np.zeros((nx,ny, 4), dtype=np.float32)
a = np.ndarray((nx,ny), dtype=np.float32)
for i in range(0, nx):
for j in range(0, ny):
pos = FSMesh[i][j].pos
normal = FSMesh[i][j].normal
area = FSMesh[i][j].area
p[i,j,0] = pos.x
p[i,j,1] = pos.y
p[i,j,2] = pos.z
p[i,j,3] = 1.0
n[i,j,0] = normal.x
n[i,j,1] = normal.y
n[i,j,2] = normal.z
a[i,j] = area
self.fs = {'N':nx*ny, 'Nx':nx, 'Ny':ny, \
'L':L, 'B':B, 'dx':dx, 'dy':dy, \
'pos':p, 'vel':V, 'normal':n, 'area':a}
# --------------------------------------------
# Sea data
# N, Nx, Ny = Number of free surfaces
# repetitions in each direction
# --------------------------------------------
self.sea = {'N':Sea[0]*Sea[1], 'Nx':Sea[0], 'Ny':Sea[1]}
# --------------------------------------------
# Body data
# N, Nx, Ny = Number of points in each
# direction
# pos = Positions
# vel = Velocities
# n = Normals
# area = Areas
# --------------------------------------------
self.b = {'N':0, 'pos':None, 'vel':None, 'normal':None, 'area':None}
# --------------------------------------------
# Waves data
# N = Number of waves
# data = Waves data
# --------------------------------------------
nW = len(waves)
w = np.ndarray((nW, 4), dtype=np.float32)
for i in range(0,nW):
w[i,0] = waves[i][0]
w[i,1] = waves[i][1]
w[i,2] = waves[i][2]
w[i,3] = waves[i][3]
self.waves = {'N':nW, 'data':w}
# --------------------------------------------
# BEM data
# N = nFS + nB
# A,B = Linear system matrix and vectors
# p = Velocity potentials (phi).
# gradp = Velocity potentials gradient
# (grad(phi)) projected over the
# normal
# dpdt = Velocity potentials time
# variation rate
# --------------------------------------------
nFS = self.fs['N']
nB = self.b['N']
N = nFS + nB
A = np.zeros((N, N), dtype=np.float32)
B = np.zeros((N), dtype=np.float32)
p = np.zeros((N), dtype=np.float32)
gp = np.zeros((N), dtype=np.float32)
dpdt = np.zeros((N), dtype=np.float32)
self.bem = {'N':N, 'A':A, 'B':B, \
'p':p, 'gradp':gp, 'dpdt':dpdt }
def execute(self):
""" Compute initial conditions. """
# --------------------------------------------
# Free surface initial condition.
# Since RK4 scheme starts on the end of
# previous step, we only write on last
# stage value (p4 and dp4)
# --------------------------------------------
nx = self.fs['Nx']
ny = self.fs['Ny']
for i in range(0,nx):
for j in range(0,ny):
# Since initial values of the potencial, and this acceleration,
# depends on z, we need to compute first the positions.
self.fs['pos'][i,j][2] = 0.
self.bem['p'][i*ny+j] = 0.
self.bem['gradp'][i*ny+j] = 0.
for w in self.waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
pos = self.fs['pos'][i,j]
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
amp = A*np.sin(k*l + phase)
self.fs['pos'][i,j][2] = self.fs['pos'][i,j][2] + amp
amp = - A*frec*np.cos(k*l + phase)
self.fs['vel'][i,j][2] = self.fs['vel'][i,j][2] + amp
# And now we can compute potentials.
for w in self.waves['data']:
A = w[0]
T = w[1]
phase = w[2]
heading = np.pi*w[3]/180.0
wl = 0.5 * grav / np.pi * T*T
k = 2.0*np.pi/wl
frec = 2.0*np.pi/T
pos = self.fs['pos'][i,j]
l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
amp = - A*frec/k*np.cos(k*l + phase)*np.exp(k*pos[2])
self.bem['p'][i*ny+j] = self.bem['p'][i*ny+j] + amp
amp = - A*frec*np.cos(k*l + phase)*np.exp(k*pos[2])
self.bem['gradp'][i*ny+j] = self.bem['gradp'][i*ny+j] + amp
# --------------------------------------------------------
# Debugging
# --------------------------------------------------------
"""
self.fs['pos'][i,j][2] = 0.
self.bem['p'][i*ny+j] = 0.
self.bem['gradp'][i*ny+j] = 0.
# We can do phi = Green's function
dx = self.fs['pos'][i,j][0]
dy = self.fs['pos'][i,j][1]
dz = 15.0 # An arbitrary value > 0
self.bem['p'][i*ny+j] = 1. / (4. * np.pi * np.sqrt(dx*dx + dy*dy + dz*dz))
self.bem['gradp'][i*ny+j] = - dz / (4. * np.pi * (dx*dx + dy*dy + dz*dz)**(1.5))
"""
# --------------------------------------------------------
# Debugging
# --------------------------------------------------------
def loadData(self, FSmesh, waves):
""" Convert data to numpy format, and create OpenCL
buffers.
@param FSmesh Initial free surface mesh.
@param waves Considered simulation waves (A,T,phi,heading).
"""
mf = cl.mem_flags
nx = len(FSmesh)
ny = len(FSmesh[0])
nW = len(waves)
# Mesh data
p = np.ndarray((nx*ny, 4), dtype=np.float32)
n = np.ndarray((nx*ny, 4), dtype=np.float32)
a = np.ndarray((nx*ny, 1), dtype=np.float32)
for i in range(0, nx):
for j in range(0, ny):
id = i*ny + j
pos = FSmesh[i][j].pos
normal = FSmesh[i][j].normal
area = FSmesh[i][j].area
p[id,0] = pos.x
p[id,1] = pos.y
p[id,2] = pos.z
p[id,3] = 1.
n[id,0] = normal.x
n[id,1] = normal.y
n[id,2] = normal.z
n[id,3] = 0.
a[id,0] = area
p_cl = cl.Buffer(self.context, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=p)
n_cl = cl.Buffer(self.context, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=n)
a_cl = cl.Buffer(self.context, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=a)
v_cl = cl.Buffer(self.context, mf.READ_WRITE, size = nx*ny*4 * np.dtype('float32').itemsize)
f_cl = cl.Buffer(self.context, mf.READ_WRITE, size = nx*ny*4 * np.dtype('float32').itemsize)
phi = cl.Buffer(self.context, mf.READ_WRITE, size = nx*ny * np.dtype('float32').itemsize)
Phi = cl.Buffer(self.context, mf.READ_WRITE, size = nx*ny * np.dtype('float32').itemsize)
self.fs = {'Nx':nx, 'Ny':ny, 'pos':p_cl, 'vel':v_cl, 'acc':f_cl, \
'normal':n_cl, 'area':a_cl, 'velPot':phi, 'accPot':Phi}
# Waves data
w = np.ndarray((nW, 4), dtype=np.float32)
for i in range(0,nW):
w[i,0] = waves[i][0]
w[i,1] = waves[i][1]
w[i,2] = waves[i][2]
w[i,3] = waves[i][3]
w_cl = cl.Buffer(self.context, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=w)
self.waves = {'N':nW, 'data':w_cl}
# Ensure that all data has been written
self.queue.finish()
def execute(self):
""" Compute initial conditions. """
# Global size computation
N = np.ndarray((2, 1), dtype=np.uint32)
N[0] = self.fs['Nx']
N[1] = self.fs['Ny']
n = np.uint32(self.waves['N'])
gSize = (globalSize(N[0]),globalSize(N[1]),)
# Kernel arguments
kernelargs = (self.fs['pos'],
self.fs['vel'],
self.fs['acc'],
self.waves['data'],
self.fs['velPot'],
self.fs['accPot'],
N, n)
# Kernel launch
self.program.FS(self.queue, gSize, None, *(kernelargs))
self.queue.finish()

View File

@ -0,0 +1,184 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
# numpy
import numpy as np
# pyOpenCL
import pyopencl as cl
import clUtils
import FreeCAD
grav=9.81
class simMatrixGen_cl:
def __init__(self, context=None, queue=None):
""" Constructor.
@param context OpenCL context where apply.
@param queue OpenCL command queue.
"""
self.context = context
self.queue = queue
self.program = clUtils.loadProgram(context, clUtils.path() + "/matrixGen.cl")
# Create OpenCL objects as null objects, that we will generate
# at the first iteration
self.A = None
self.B = None
self.dB = None
self.pos = None
self.area = None
self.normal = None
self.p = None
self.gradp = None
def execute(self, fs, waves, sea, bem, body, t):
""" Compute system matrix.
@param fs Free surface instance.
@param waves Waves instance.
@param sea Sea boundary instance.
@param bem Boundary Element Method instance.
@param body Body instance.
@param t Simulation time.
"""
# Create/set OpenCL buffers
self.setBuffers(fs,waves,sea,bem,body)
# Convert constant parameters
L = np.float32(fs['L'])
B = np.float32(fs['B'])
dx = np.float32(fs['dx'])
dy = np.float32(fs['dy'])
T = np.float32(t)
# Get dimensions for OpenCL execution
nx = np.uint32(fs['Nx'])
ny = np.uint32(fs['Ny'])
nFS = np.uint32(fs['N'])
nB = np.uint32(body['N'])
n = np.uint32(nFS + nB)
nSeax = np.int32(sea['Nx'])
nSeay = np.int32(sea['Ny'])
nW = np.uint32(waves['N'])
# Call OpenCL to work
gSize = (clUtils.globalSize(n),)
kernelargs = (self.A,
self.B,
self.pos,
self.area,
self.normal,
self.bem_p,
self.bem_dp,
self.waves,
L,
B,
dx,
dy,
T,
nx,
ny,
nFS,
nB,
n,
nSeax,
nSeay,
nW)
self.program.matrixGen(self.queue, gSize, None, *(kernelargs))
self.queue.finish()
# Read output data
events = []
events.append(cl.enqueue_read_buffer(self.queue, self.A, bem['A'].reshape((n*n))))
events.append(cl.enqueue_read_buffer(self.queue, self.B, bem['B']))
# events.append(cl.enqueue_read_buffer(self.queue, self.dB, bem['dB']))
for e in events:
e.wait()
# --------------------------------------------------------
# Debugging
# --------------------------------------------------------
"""
for i in range(0,fs['Nx']):
for j in range(0,fs['Ny']):
x = fs['pos'][i,j,0]
y = fs['pos'][i,j,1]
FreeCAD.Console.PrintMessage("pos = {0},{1}\n".format(x,y))
A = np.dot(bem['A'][i*fs['Ny'] + j,:], bem['gradp'][:])
B = bem['B'][i*fs['Ny'] + j]
phi = 2.0 * (B - A)
bem['p'][i*fs['Ny'] + j] = phi
"""
# --------------------------------------------------------
# Debugging
# --------------------------------------------------------
return
def setBuffers(self, fs, waves, sea, bem, body):
""" Create/set OpenCL required buffers.
@param fs Free surface instance.
@param waves Waves instance.
@param sea Sea boundary instance.
@param bem Boundary Element Method instance.
@param body Body instance.
"""
# Get dimensions
nFS = fs['N']
nB = body['N']
n = nFS + nB
nW = waves['N']
# Generate arrays for positions, areas and normals
pos = np.zeros((n, 4), dtype=np.float32)
area = np.zeros((n ), dtype=np.float32)
normal = np.zeros((n, 4), dtype=np.float32)
p = np.zeros((n ), dtype=np.float32)
dp = np.zeros((n ), dtype=np.float32)
w = np.zeros((nW,4), dtype=np.float32)
pos[0:nFS] = fs['pos'].reshape((nFS,4))
area[0:nFS] = fs['area'].reshape((nFS))
normal[0:nFS] = fs['normal'].reshape((nFS,4))
nx = fs['Nx']
ny = fs['Ny']
p[0:n] = bem['p']
dp[0:n] = bem['gradp']
w[0:nW] = waves['data']
# Create OpenCL objects if not already generated
if not self.A:
mf = cl.mem_flags
self.A = cl.Buffer( self.context, mf.WRITE_ONLY, size = n*n * np.dtype('float32').itemsize )
self.B = cl.Buffer( self.context, mf.WRITE_ONLY, size = n * np.dtype('float32').itemsize )
self.dB = cl.Buffer( self.context, mf.WRITE_ONLY, size = n * np.dtype('float32').itemsize )
self.pos = cl.Buffer( self.context, mf.READ_ONLY, size = n*4 * np.dtype('float32').itemsize )
self.area = cl.Buffer( self.context, mf.READ_ONLY, size = n * np.dtype('float32').itemsize )
self.normal = cl.Buffer( self.context, mf.READ_ONLY, size = n*4 * np.dtype('float32').itemsize )
self.bem_p = cl.Buffer( self.context, mf.READ_ONLY, size = n * np.dtype('float32').itemsize )
self.bem_dp = cl.Buffer( self.context, mf.READ_ONLY, size = n * np.dtype('float32').itemsize )
self.waves = cl.Buffer( self.context, mf.READ_ONLY, size = nW*4 * np.dtype('float32').itemsize )
# Transfer data to buffers
events = []
events.append(cl.enqueue_write_buffer(self.queue, self.pos, pos))
events.append(cl.enqueue_write_buffer(self.queue, self.area, area))
events.append(cl.enqueue_write_buffer(self.queue, self.normal, normal))
events.append(cl.enqueue_write_buffer(self.queue, self.bem_p, p))
events.append(cl.enqueue_write_buffer(self.queue, self.bem_dp, dp))
events.append(cl.enqueue_write_buffer(self.queue, self.waves, w))
for e in events:
e.wait()

View File

@ -0,0 +1,56 @@
\chapter{Introduction}
\label{s:introduction}
%
\section{Objective}
%
The objective of this document is introduce briefly how the waves of the
seakeeping simulator are propagated.\rc
%
In the seakeeping simulator Boundary Elements Method (BEM) will be used,
that is detailed described in several books, like \citet{bem_2007}.
\citet{vinayan2007} gives a detailed description of the propagation
of waves in a 2D case, and is a good starting point.\rc
%
We will start briefly describing the governing equations in order to can
start working with the 2D problem. First the incident waves over our
computational domain will be described, introducing also the potential,
discussing then the BEM applied to this case. As we will see the Laplace
problem in the 2D case will not be really useful for us.\rc
%
After that we can start working in the 3D case, that is our real objective.
The incident waves will be rewritten, and the Laplace problem and the BEM
application purposed again.
%
\chapter{Governing equations}
\label{s:governing_equations}
%
Assuming no viscous fluid (that allows to transform Navier-Stokes
equations into Euler ones), and imposing an initial condition such
that\footnote{With no viscous fluid this condition is preserved along the
time}:
%
\begin{eqnarray}
\rotational \bs{u} = 0
\end{eqnarray}
%
The fluid velocity derives from a scalar function potential $\phi$
%
\begin{eqnarray}
\label{eq:governing_equations:v_potential}
\gradient \phi = \bs{u}
\end{eqnarray}
%
Then the Navier-Stokes equations can be rewriten as a Laplacian problem
and Bernoulli equation:
%
\begin{eqnarray}
\label{eq:governing_equations:laplace}
\laplacian \phi = & 0
\\
\label{eq:governing_equations:bernoulli}
p = & - \rho \left( \vert \bs{u} \vert^2 + g \bs{z} \right)
\end{eqnarray}
%
And in order to solve the Laplace problem \ref{eq:governing_equations:laplace}
we will use the BEM as described by \citet{bem_2007}.
%

View File

@ -0,0 +1,91 @@
@Comment{THE COMMENTS IN BIBTEX ARE IMPLEMENTED THIS WAY!}
@STRING(OE="Ocean Engineering")
@STRING{AA = "Astron. Astrophys."}
@STRING{ACA = "Extraits des comptes rendus des s\'eances de l'Acad\'emie des Sciences"}
@STRING{AG = "Adv. Geophys."}
@STRING{AIAAJ = "AIAA J."}
@STRING{AIAAP = "AIAA Pap."}
@STRING{AMR = "Appl. Mech. Rev."}
@STRING{ARFM = "Annu. Rev. Fluid Mech."}
@STRING{ARAA = "Annu. Rev. Astron. Astrophy."}
@STRING{AMCFD = "Advanced Methods for Computational Fluid Dynamics"}
@STRING{AMC = "Applied Mathematics and Computations"}
@STRING{ANM = "Applied Numerical Mathematics"}
@STRING{BAPS = "Bull. Am. Phys. Soc."}
@STRING{CUP = "Cambridge University Press"}
@STRING{CMAME = "Comput. Methods Appl. Mech. Engrg."}
@STRING{DI = "Dantec Information"}
@STRING{EF = "Expts. Fluids"}
@STRING{EJMF = "Eur. J. Mech. B/Fluids"}
@STRING{IJHFF = "Int. J. Heat and Fluid Flow"}
@STRING{IJHMT = "Int. J. Heat and Mass Transfer"}
@STRING{IJIE = "Int. J. Impact Engng."}
@STRING{IJNMF = "Int. J. Numer. Methods Fluids"}
@STRING{INPG = "Institut National Polytechnique Grenoble"}
@STRING{JA = "J. Aircraft"}
@STRING{JAM = "J. Applied Mech."}
@STRING{JAMTP = "J. Appl. Mech. Tech. Phys."}
@STRING{JAP = "J. App. Phys."}
@STRING{JAS = "J. Atmos. Sci."}
@STRING{JCP = "J. Comp. Phys."}
@STRING{JCAM = "J. Computational and Applied Mathematics"}
@STRING{JFE = "J. Fluids Engine."}
@STRING{JFM = "J. Fluid Mech."}
@STRING{JHE = "J. Hydraulic Engineering"}
@STRING{JM = "Journal de M\'ecanique"}
@STRING{JOT = "Journal of Turbulence"}
@STRING{JRNBS = "J. Res. Nat. Bur. Standards"}
@STRING{JTAM = "J. Theo. and Appl. Mech."}
@STRING{JWEIA = "J. Wind Engng. Indust. Aerodyn."}
@STRING{MC = "Math. Comp."}
@STRING{ME = "Meccanica"}
@STRING{MRP = "Mathematics Reports and Preprints"}
@STRING{MWR = "Mon. Weather Rev."}
@STRING{NACA = "NACA"}
@STRING{PFA = "Phys. Fluids A"}
@STRING{PFL = "Phys. Fluids Lett."}
@STRING{PFO = "Phys. Fluids"}
@STRING{PRA = "Phys. Review A"}
@STRING{PRE = "Phys. Review E"}
@STRING{PRL = "Phys. Review Lett."}
@STRING{PTRS = "Phil. Trans. Roy. Soc."}
@STRING{QJRMS = "Q. J. R. Meteorol. Soc."}
@STRING{RA = "Rech. Aeros."}
@STRING{RF = "Rapport Final"}
@STRING{SJAP = "Sov. J. Appl. Phys."}
@STRING{SSSR = "Dokl. Akad. Nauk. SSSR"}
@STRING{SV = "Springer-Verlag"}
@STRING{TAM = "Theoret. and Applied Mech."}
@STRING{TAJ = "The Astrophysical Journal"}
@STRING{TCFD = "Theoret. Comput. Fluid Dynamics"}
@STRING{EJBE = "Electronic Journal of Boundary Elements"}
@BOOK{bem_2007,
AUTHOR = {Whye-Teong Ang},
EDITOR = {Universal Publishers},
TITLE = {A Beginners Course in Boundary Element Methods},
PUBLISHER = {Cambridge University Press, New York},
YEAR = {2007},
VOLUME = {},
SERIES = {},
ADDRESS = {},
EDITION = {},
MONTH = {}
}
@ARTICLE{vinayan2007,
AUTHOR="Vinayan, V. and Kinnas, S. A. ",
TITLE="A BEM for the Propagation of Nonlinear Planar Free-surface Waves",
JOURNAL=EJBE,
VOLUME=5,
PAGES="17-40",
YEAR=2007,
}
@PHDTHESIS{yang2004,
AUTHOR="Jinghai Yang",
TITLE="Time domain, nonlinear theories on ship motions",
SCHOOL="University of Hawaii",
YEAR=2004,
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,911 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="696.80151"
height="696.78088"
id="svg2"
version="1.1"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="Omega.svg">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible">
<path
id="path3819"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.8,0,0,-0.8,-10,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Lstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lstart"
style="overflow:visible">
<path
id="path3816"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(0.8,0,0,0.8,10,0)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.5"
inkscape:cx="172.67613"
inkscape:cy="415.00616"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1366"
inkscape:window-height="722"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-75.975395,-284.00604)">
<rect
y="285.25604"
x="308.66736"
height="231.42857"
width="231.42857"
id="rect3792"
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect3794"
width="231.42857"
height="231.42857"
x="308.66736"
y="748.10834" />
<rect
y="516.68781"
x="77.225395"
height="231.42857"
width="231.42857"
id="rect3796"
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect3798"
width="231.42857"
height="231.42857"
x="77.225395"
y="285.25604" />
<rect
y="748.10834"
x="77.225395"
height="231.42857"
width="231.42857"
id="rect3800"
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect3802"
width="231.42857"
height="231.42857"
x="540.09833"
y="516.68781" />
<rect
y="285.25604"
x="540.09833"
height="231.42857"
width="231.42857"
id="rect3804"
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect3806"
width="231.42857"
height="231.42857"
x="540.09833"
y="748.10834" />
<rect
style="fill:none;stroke:#ff0000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect3010"
width="231.42857"
height="231.42857"
x="275.71429"
y="144.56863"
transform="translate(32.95305,372.1192)" />
<g
id="g3816"
transform="matrix(0.92795508,0,0,0.92795508,22.248227,37.217218)">
<rect
y="517.0835"
x="309.31049"
height="62.225395"
width="62.225395"
id="rect3808"
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0" />
<rect
transform="scale(-1,1)"
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
id="rect3810"
width="62.225395"
height="62.225395"
x="-433.73477"
y="517.0835" />
<rect
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
id="rect3812"
width="62.225395"
height="62.225395"
x="433.73032"
y="517.0835" />
<rect
y="517.0835"
x="-558.1546"
height="62.225395"
width="62.225395"
id="rect3814"
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
transform="scale(-1,1)" />
</g>
<g
transform="matrix(0.92795508,0,0,-0.92795508,22.248227,1112.322)"
id="g3822">
<rect
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
id="rect3824"
width="62.225395"
height="62.225395"
x="309.31049"
y="517.0835" />
<rect
y="517.0835"
x="-433.73477"
height="62.225395"
width="62.225395"
id="rect3826"
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
transform="scale(-1,1)" />
<rect
y="517.0835"
x="433.73032"
height="62.225395"
width="62.225395"
id="rect3828"
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0" />
<rect
transform="scale(-1,1)"
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
id="rect3830"
width="62.225395"
height="62.225395"
x="-558.1546"
y="517.0835" />
</g>
<g
transform="matrix(0.92795508,0,0,0.92795508,22.248227,152.62103)"
id="g3832">
<rect
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
id="rect3834"
width="62.225395"
height="62.225395"
x="309.31049"
y="517.0835" />
<rect
y="517.0835"
x="-433.73477"
height="62.225395"
width="62.225395"
id="rect3836"
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
transform="scale(-1,1)" />
<rect
y="517.0835"
x="433.73032"
height="62.225395"
width="62.225395"
id="rect3838"
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0" />
<rect
transform="scale(-1,1)"
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
id="rect3840"
width="62.225395"
height="62.225395"
x="-558.1546"
y="517.0835" />
</g>
<g
id="g3842"
transform="matrix(0.92795508,0,0,-0.92795508,22.248227,1227.7258)">
<rect
y="517.0835"
x="309.31049"
height="62.225395"
width="62.225395"
id="rect3844"
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0" />
<rect
transform="scale(-1,1)"
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
id="rect3846"
width="62.225395"
height="62.225395"
x="-433.73477"
y="517.0835" />
<rect
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
id="rect3848"
width="62.225395"
height="62.225395"
x="433.73032"
y="517.0835" />
<rect
y="517.0835"
x="-558.1546"
height="62.225395"
width="62.225395"
id="rect3850"
style="fill:none;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
transform="scale(-1,1)" />
</g>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="317.20996"
y="510.84082"
id="text3852"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3854"
x="317.20996"
y="510.84082">dx</tspan></text>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="402.06277"
y="319.2149"
id="text3856"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3858"
x="402.06277"
y="319.2149">Dx</tspan></text>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="432.95306"
y="644.54498"
id="text3860"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3862"
x="432.95306"
y="644.54498">Z(x<tspan
style="font-size:65.00091553%;baseline-shift:sub"
id="tspan3864">a</tspan>,y<tspan
style="font-size:65.00091553%;baseline-shift:sub"
id="tspan3900">a</tspan>)</tspan></text>
<g
id="g3870">
<path
transform="translate(32.95305,372.1192)"
inkscape:connector-curvature="0"
id="path3866"
d="m 387.25,255.92578 9.875,9.875"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.07805,628.04498 -9.875,9.875"
id="path3868"
inkscape:connector-curvature="0" />
</g>
<g
id="g3880"
transform="translate(-240,0)">
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 387.25,255.92578 9.875,9.875"
id="path3882"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
inkscape:connector-curvature="0"
id="path3884"
d="m 430.07805,628.04498 -9.875,9.875"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<text
xml:space="preserve"
style="font-size:40.41842651px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="117.07106"
y="390.29718"
id="text3904"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3906"
x="117.07106"
y="390.29718"
style="font-size:22px">Z(x<tspan
style="font-size:22px;baseline-shift:sub"
id="tspan3908">a</tspan>-Dx,y<tspan
id="tspan3910"
style="font-size:22px;baseline-shift:sub">a</tspan>+Dy)</tspan></text>
<g
transform="matrix(1.0104607,0,0,1.0104607,-244.524,-232.41011)"
id="g3912">
<path
transform="translate(32.95305,372.1192)"
inkscape:connector-curvature="0"
id="path3914"
d="m 387.25,255.92578 9.875,9.875"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.07805,628.04498 -9.875,9.875"
id="path3916"
inkscape:connector-curvature="0" />
</g>
<g
id="g3926"
transform="matrix(1.0104607,0,0,1.0104607,-244.524,225.58989)">
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 387.25,255.92578 9.875,9.875"
id="path3928"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
inkscape:connector-curvature="0"
id="path3930"
d="m 430.07805,628.04498 -9.875,9.875"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="128.07944"
y="616.26074"
id="text3932"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3934"
x="128.07944"
y="616.26074"
style="font-size:22px">Z(x<tspan
style="font-size:22px;baseline-shift:sub"
id="tspan3936">a</tspan>-Dx,y<tspan
id="tspan3938"
style="font-size:22px;baseline-shift:sub">a</tspan>)</tspan></text>
<g
id="g3940"
transform="translate(-240,0)">
<path
transform="translate(32.95305,372.1192)"
inkscape:connector-curvature="0"
id="path3942"
d="m 387.25,255.92578 9.875,9.875"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.07805,628.04498 -9.875,9.875"
id="path3944"
inkscape:connector-curvature="0" />
</g>
<g
id="g3954"
transform="matrix(1.0104607,0,0,1.0104607,-244.524,-232.41011)">
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 387.25,255.92578 9.875,9.875"
id="path3956"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
inkscape:connector-curvature="0"
id="path3958"
d="m 430.07805,628.04498 -9.875,9.875"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<text
xml:space="preserve"
style="font-size:40.41842651px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="117.07106"
y="848.29718"
id="text3960"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3962"
x="117.07106"
y="848.29718"
style="font-size:22px">Z(x<tspan
style="font-size:22px;baseline-shift:sub"
id="tspan3964">a</tspan>-Dx,y<tspan
id="tspan3966"
style="font-size:22px;baseline-shift:sub">a</tspan>-Dy)</tspan></text>
<g
transform="matrix(1.0104607,0,0,1.0104607,-244.524,225.58989)"
id="g3968">
<path
transform="translate(32.95305,372.1192)"
inkscape:connector-curvature="0"
id="path3970"
d="m 387.25,255.92578 9.875,9.875"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.07805,628.04498 -9.875,9.875"
id="path3972"
inkscape:connector-curvature="0" />
</g>
<text
sodipodi:linespacing="125%"
id="text4002"
y="390.29718"
x="581.07104"
style="font-size:40.41842651px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
xml:space="preserve"><tspan
style="font-size:22px"
y="390.29718"
x="581.07104"
id="tspan4004"
sodipodi:role="line">Z(x<tspan
id="tspan4006"
style="font-size:22px;baseline-shift:sub">a</tspan>-Dx,y<tspan
style="font-size:22px;baseline-shift:sub"
id="tspan4008">a</tspan>+Dy)</tspan></text>
<text
sodipodi:linespacing="125%"
id="text4010"
y="616.26074"
x="592.07947"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
xml:space="preserve"><tspan
style="font-size:22px"
y="616.26074"
x="592.07947"
id="tspan4012"
sodipodi:role="line">Z(x<tspan
id="tspan4014"
style="font-size:22px;baseline-shift:sub">a</tspan>-Dx,y<tspan
style="font-size:22px;baseline-shift:sub"
id="tspan4016">a</tspan>)</tspan></text>
<g
id="g4018"
transform="translate(224,0)">
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 387.25,255.92578 9.875,9.875"
id="path4020"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
inkscape:connector-curvature="0"
id="path4022"
d="m 430.07805,628.04498 -9.875,9.875"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
transform="matrix(1.0104607,0,0,1.0104607,219.476,-232.41011)"
id="g4024">
<path
transform="translate(32.95305,372.1192)"
inkscape:connector-curvature="0"
id="path4026"
d="m 387.25,255.92578 9.875,9.875"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.07805,628.04498 -9.875,9.875"
id="path4028"
inkscape:connector-curvature="0" />
</g>
<text
sodipodi:linespacing="125%"
id="text4030"
y="848.29718"
x="581.07104"
style="font-size:40.41842651px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
xml:space="preserve"><tspan
style="font-size:22px"
y="848.29718"
x="581.07104"
id="tspan4032"
sodipodi:role="line">Z(x<tspan
id="tspan4034"
style="font-size:22px;baseline-shift:sub">a</tspan>-Dx,y<tspan
style="font-size:22px;baseline-shift:sub"
id="tspan4036">a</tspan>-Dy)</tspan></text>
<g
id="g4038"
transform="matrix(1.0104607,0,0,1.0104607,219.476,225.58989)">
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 387.25,255.92578 9.875,9.875"
id="path4040"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
inkscape:connector-curvature="0"
id="path4042"
d="m 430.07805,628.04498 -9.875,9.875"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<text
xml:space="preserve"
style="font-size:40.41842651px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="361.07104"
y="390.29718"
id="text4044"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4046"
x="361.07104"
y="390.29718"
style="font-size:22px">Z(x<tspan
style="font-size:22px;baseline-shift:sub"
id="tspan4048">a</tspan>-Dx,y<tspan
id="tspan4050"
style="font-size:22px;baseline-shift:sub">a</tspan>+Dy)</tspan></text>
<g
id="g4052"
transform="matrix(1.0104607,0,0,1.0104607,-0.524,-232.41011)">
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 387.25,255.92578 9.875,9.875"
id="path4054"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
inkscape:connector-curvature="0"
id="path4056"
d="m 430.07805,628.04498 -9.875,9.875"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<text
xml:space="preserve"
style="font-size:40.41842651px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="361.07104"
y="848.29718"
id="text4058"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4060"
x="361.07104"
y="848.29718"
style="font-size:22px">Z(x<tspan
style="font-size:22px;baseline-shift:sub"
id="tspan4062">a</tspan>-Dx,y<tspan
id="tspan4064"
style="font-size:22px;baseline-shift:sub">a</tspan>-Dy)</tspan></text>
<g
transform="matrix(1.0104607,0,0,1.0104607,-0.524,225.58989)"
id="g4066">
<path
transform="translate(32.95305,372.1192)"
inkscape:connector-curvature="0"
id="path4068"
d="m 387.25,255.92578 9.875,9.875"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.07805,628.04498 -9.875,9.875"
id="path4070"
inkscape:connector-curvature="0" />
</g>
<text
sodipodi:linespacing="125%"
id="text4091"
y="550.84082"
x="257.20996"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
xml:space="preserve"><tspan
y="550.84082"
x="257.20996"
id="tspan4093"
sodipodi:role="line">dy</tspan></text>
<text
sodipodi:linespacing="125%"
id="text4095"
y="425.2149"
x="310.06277"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
xml:space="preserve"><tspan
y="425.2149"
x="310.06277"
id="tspan4097"
sodipodi:role="line">Dy</tspan></text>
<g
id="g4099"
transform="translate(-86,-88)"
style="stroke:#ff0000;stroke-opacity:1">
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 387.25,255.92578 9.875,9.875"
id="path4101"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
inkscape:connector-curvature="0"
id="path4103"
d="m 430.07805,628.04498 -9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
style="stroke:#ff0000;stroke-opacity:1"
transform="translate(-28,-88)"
id="g4105">
<path
transform="translate(32.95305,372.1192)"
inkscape:connector-curvature="0"
id="path4107"
d="m 387.25,255.92578 9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.07805,628.04498 -9.875,9.875"
id="path4109"
inkscape:connector-curvature="0" />
</g>
<g
style="stroke:#ff0000;stroke-opacity:1"
transform="translate(28,-88)"
id="g4111">
<path
transform="translate(32.95305,372.1192)"
inkscape:connector-curvature="0"
id="path4113"
d="m 387.25,255.92578 9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.07805,628.04498 -9.875,9.875"
id="path4115"
inkscape:connector-curvature="0" />
</g>
<g
id="g4117"
transform="translate(86,-88)"
style="stroke:#ff0000;stroke-opacity:1">
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 387.25,255.92578 9.875,9.875"
id="path4119"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
inkscape:connector-curvature="0"
id="path4121"
d="m 430.07805,628.04498 -9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
style="stroke:#ff0000;stroke-opacity:1"
transform="translate(-86,-30)"
id="g4123">
<path
transform="translate(32.95305,372.1192)"
inkscape:connector-curvature="0"
id="path4125"
d="m 387.25,255.92578 9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.07805,628.04498 -9.875,9.875"
id="path4127"
inkscape:connector-curvature="0" />
</g>
<g
id="g4129"
transform="translate(-28,-30)"
style="stroke:#ff0000;stroke-opacity:1">
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 387.25,255.92578 9.875,9.875"
id="path4131"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
inkscape:connector-curvature="0"
id="path4133"
d="m 430.07805,628.04498 -9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
id="g4135"
transform="translate(28,-30)"
style="stroke:#ff0000;stroke-opacity:1">
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 387.25,255.92578 9.875,9.875"
id="path4137"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
inkscape:connector-curvature="0"
id="path4139"
d="m 430.07805,628.04498 -9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
style="stroke:#ff0000;stroke-opacity:1"
transform="translate(86,-30)"
id="g4141">
<path
transform="translate(32.95305,372.1192)"
inkscape:connector-curvature="0"
id="path4143"
d="m 387.25,255.92578 9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.07805,628.04498 -9.875,9.875"
id="path4145"
inkscape:connector-curvature="0" />
</g>
<g
id="g4147"
transform="translate(-86,28)"
style="stroke:#ff0000;stroke-opacity:1">
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 387.25,255.92578 9.875,9.875"
id="path4149"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
inkscape:connector-curvature="0"
id="path4151"
d="m 430.07805,628.04498 -9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
style="stroke:#ff0000;stroke-opacity:1"
transform="translate(-28,28)"
id="g4153">
<path
transform="translate(32.95305,372.1192)"
inkscape:connector-curvature="0"
id="path4155"
d="m 387.25,255.92578 9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.07805,628.04498 -9.875,9.875"
id="path4157"
inkscape:connector-curvature="0" />
</g>
<g
style="stroke:#ff0000;stroke-opacity:1"
transform="translate(28,28)"
id="g4159">
<path
transform="translate(32.95305,372.1192)"
inkscape:connector-curvature="0"
id="path4161"
d="m 387.25,255.92578 9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.07805,628.04498 -9.875,9.875"
id="path4163"
inkscape:connector-curvature="0" />
</g>
<g
id="g4165"
transform="translate(86,28)"
style="stroke:#ff0000;stroke-opacity:1">
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 387.25,255.92578 9.875,9.875"
id="path4167"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
inkscape:connector-curvature="0"
id="path4169"
d="m 430.07805,628.04498 -9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
style="stroke:#ff0000;stroke-opacity:1"
transform="translate(-86,86)"
id="g4171">
<path
transform="translate(32.95305,372.1192)"
inkscape:connector-curvature="0"
id="path4173"
d="m 387.25,255.92578 9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.07805,628.04498 -9.875,9.875"
id="path4175"
inkscape:connector-curvature="0" />
</g>
<g
id="g4177"
transform="translate(-28,86)"
style="stroke:#ff0000;stroke-opacity:1">
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 387.25,255.92578 9.875,9.875"
id="path4179"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
inkscape:connector-curvature="0"
id="path4181"
d="m 430.07805,628.04498 -9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
id="g4183"
transform="translate(28,86)"
style="stroke:#ff0000;stroke-opacity:1">
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 387.25,255.92578 9.875,9.875"
id="path4185"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
inkscape:connector-curvature="0"
id="path4187"
d="m 430.07805,628.04498 -9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
style="stroke:#ff0000;stroke-opacity:1"
transform="translate(86,86)"
id="g4189">
<path
transform="translate(32.95305,372.1192)"
inkscape:connector-curvature="0"
id="path4191"
d="m 387.25,255.92578 9.875,9.875"
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.07805,628.04498 -9.875,9.875"
id="path4193"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -0,0 +1,206 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="802.74475"
height="477.42578"
id="svg2"
version="1.1"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="Integral.png">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible">
<path
id="path3819"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.8,0,0,-0.8,-10,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Lstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lstart"
style="overflow:visible">
<path
id="path3816"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(0.8,0,0,0.8,10,0)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.5"
inkscape:cx="172.67613"
inkscape:cy="415.00616"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1366"
inkscape:window-height="722"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-32.95305,-372.1192)">
<path
sodipodi:nodetypes="csscccc"
inkscape:connector-curvature="0"
id="path3784"
d="m 179.37772,499.50504 c 0,0 58.04352,-81.42857 145.10879,-81.42857 87.06526,0 54.81886,161.42853 145.10876,161.42853 90.2899,0 141.88415,-81.42853 141.88415,-81.42853 l 0,308.57143 -432.1017,0 z"
style="fill:#00c8cd;fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="cssc"
inkscape:connector-curvature="0"
id="path3786"
d="m 179.37772,499.50504 c 0,0 58.04352,-81.42857 145.10879,-81.42857 87.06526,0 54.81886,161.42857 145.10876,161.42857 90.2899,0 141.88415,-81.42857 141.88415,-81.42857"
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3788"
d="m 611.47942,806.6479 -432.1017,0"
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="344.31989"
y="841.2403"
id="text3790"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3792"
x="344.31989"
y="841.2403">δΩ<tspan
style="font-size:65.00091553%;baseline-shift:sub"
id="tspan3794">Bottom</tspan></tspan></text>
<text
sodipodi:linespacing="125%"
id="text3796"
y="401.2403"
x="344.31989"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
xml:space="preserve"><tspan
y="401.2403"
x="344.31989"
id="tspan3798"
sodipodi:role="line">δΩ<tspan
style="font-size:65.00091553%;baseline-shift:sub"
id="tspan3802">FS</tspan></tspan></text>
<text
sodipodi:linespacing="125%"
id="text3804"
y="701.2403"
x="384.31989"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
xml:space="preserve"><tspan
y="701.2403"
x="384.31989"
id="tspan3806"
sodipodi:role="line">Ω<tspan
id="tspan3808"
style="font-size:65.00091553%;baseline-shift:sub" /></tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Lend)"
d="m 164.51273,655.37223 -71.720831,0"
id="path3810"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4806"
d="m 623.12199,655.37223 71.72083,0"
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Lend)" />
<path
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:5, 5;stroke-dashoffset:0"
d="m 177.64471,499.80874 c 0,0 -26.26396,62.62946 -51.51778,62.62946 -25.25381,0 -42.426404,-124.24876 -63.639608,-124.24876 -21.213203,0 -28.284271,33.33503 -28.284271,33.33503 m 0,336.3808 145.461969,0"
id="path4808"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssccc" />
<path
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 34.20305,471.52447 0,336.3808"
id="path4812"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:5, 5;stroke-dashoffset:0"
d="m 609.71429,496.6479 c 0,0 15.71428,-65.71429 45.71428,-65.71429 30,0 50,68.57143 50,68.57143 m 0,307.31617 -94.28571,0"
id="path4814"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csccc" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4816"
d="m 705.42857,499.50504 0,307.31617"
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<text
sodipodi:linespacing="125%"
id="text4818"
y="721.2403"
x="42.319893"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
xml:space="preserve"><tspan
y="721.2403"
x="42.319893"
id="tspan4820"
sodipodi:role="line">δΩ<tspan
style="font-size:65.00091553%;baseline-shift:sub"
id="tspan4824">Inlet</tspan></tspan></text>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="714.31989"
y="721.2403"
id="text4826"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4828"
x="714.31989"
y="721.2403">δΩ<tspan
style="font-size:65.00091553%;baseline-shift:sub"
id="tspan4832">Outlet</tspan></tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,222 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="1127.1927"
height="447.42578"
id="svg2"
version="1.1"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="Omega2.png">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible">
<path
id="path3819"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.8,0,0,-0.8,-10,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Lstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lstart"
style="overflow:visible">
<path
id="path3816"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(0.8,0,0,0.8,10,0)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="489.03395"
inkscape:cy="286.35792"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1366"
inkscape:window-height="722"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(87.49495,-402.1192)">
<path
sodipodi:nodetypes="csscccc"
inkscape:connector-curvature="0"
id="path3784"
d="m 179.37772,499.50504 c 0,0 58.04352,-81.42857 145.10879,-81.42857 87.06526,0 54.81886,161.42853 145.10876,161.42853 90.2899,0 141.88415,-81.42853 141.88415,-81.42853 l 0,308.57143 -432.1017,0 z"
style="fill:#00c8cd;fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="cssc"
inkscape:connector-curvature="0"
id="path3786"
d="m 179.37772,499.50504 c 0,0 58.04352,-81.42857 145.10879,-81.42857 87.06526,0 54.81886,161.42857 145.10876,161.42857 90.2899,0 141.88415,-81.42857 141.88415,-81.42857"
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3788"
d="m 904.91871,806.6479 -989.239317,0"
style="fill:none;stroke:#000000;stroke-width:3.78266335;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:7.56532669, 7.56532669;stroke-dashoffset:0" />
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="344.31989"
y="841.2403"
id="text3790"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3792"
x="344.31989"
y="841.2403">δΩ<tspan
style="font-size:65.00091553%;baseline-shift:sub"
id="tspan3794">Bottom</tspan></tspan></text>
<text
sodipodi:linespacing="125%"
id="text3796"
y="431.2403"
x="380.03418"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
xml:space="preserve"><tspan
y="431.2403"
x="380.03418"
id="tspan3798"
sodipodi:role="line">δΩ<tspan
style="font-size:65.00091553%;baseline-shift:sub"
id="tspan3802">FS</tspan></tspan></text>
<text
sodipodi:linespacing="125%"
id="text3804"
y="701.2403"
x="384.31989"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
xml:space="preserve"><tspan
y="701.2403"
x="384.31989"
id="tspan3806"
sodipodi:role="line">Ω<tspan
id="tspan3808"
style="font-size:65.00091553%;baseline-shift:sub" /></tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:5, 5;stroke-dashoffset:0"
d="m -85.79695,471.52447 0,336.3808"
id="path4812"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4816"
d="m 905.42857,499.50504 0,307.31617"
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:5, 5;stroke-dashoffset:0" />
<text
sodipodi:linespacing="125%"
id="text4818"
y="721.2403"
x="-77.680107"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
xml:space="preserve"><tspan
y="721.2403"
x="-77.680107"
id="tspan4820"
sodipodi:role="line">δΩ<tspan
style="font-size:65.00091553%;baseline-shift:sub"
id="tspan4824">Inlet</tspan></tspan></text>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="918.31989"
y="721.2403"
id="text4826"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4828"
x="918.31989"
y="721.2403">δΩ<tspan
style="font-size:65.00091553%;baseline-shift:sub"
id="tspan4832">Outlet</tspan></tspan></text>
<path
style="fill:none;stroke:#ff0000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 146.21958,127.15539 c 0,0 -44.19417,98.74241 -78.539359,98.74241 -34.345187,0 -37.375645,-155.563495 -70.7106786,-155.563495 -33.3350344,0 -22.8682764,100.287745 -57.9011554,100.287745 -35.032879,0 -58.266387,-72.003473 -58.266387,-72.003473"
id="path3809"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<path
style="fill:none;stroke:#ff0000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 578.57143,125.28292 c 0,0 38.63178,-64.039987 56.81452,-64.039987 18.18275,0 38.3858,130.309677 58.58885,130.309677 20.20305,0 45.45686,-103.035559 75.76144,-103.035559 30.30458,0 27.27412,78.791899 52.52793,78.791899 25.25382,0 50.50763,-40.4061 50.50763,-40.4061"
id="path3811"
inkscape:connector-curvature="0"
transform="translate(32.95305,372.1192)" />
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="-59.96582"
y="431.2403"
id="text3813"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3815"
x="-59.96582"
y="431.2403">δΩ<tspan
id="tspan3817"
style="font-size:65.00091553%;baseline-shift:sub;fill:#ff0000;fill-opacity:1">FS,I</tspan></tspan></text>
<text
sodipodi:linespacing="125%"
id="text3819"
y="431.2403"
x="680.03418"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
xml:space="preserve"><tspan
y="431.2403"
x="680.03418"
id="tspan3821"
sodipodi:role="line">δΩ<tspan
style="font-size:65.00091553%;baseline-shift:sub;fill:#ff0000;fill-opacity:1"
id="tspan3823">FS,I</tspan></tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

View File

@ -0,0 +1,196 @@
\chapter{Waves propagations in 2D plane}
\label{s:laplace2D}
%
\section{General}
%
In this chapter the 2D case will be discussed, looking for
a method to solve the BEM using only the information about
the free surface. As we will see is not possible to do it in
the 2D case, and may move to 3D case.
%
\section{Incident waves}
%
First for all we need to describe the incident waves, that are
the waves out of our computational domain.
%
\begin{eqnarray}
\label{eq:laplace2D:incident_waves}
\begin{array}{rcl}
z(x,t) & = & \dsty{\sum_{j=1}^{n_{waves}}} a_j \sin\left(k_j x - \omega_j t + \delta_j \right)
\\
v_z(x,t) & = & \dsty{\sum_{j=1}^{n_{waves}}} - a_j \omega_j \cos\left(k_j x - \omega_j t + \delta_j \right)
\end{array}
\end{eqnarray}
%
The phase velocity for the waves in the most general case can
be written as:
%
\begin{eqnarray}
\label{eq:laplace2D:c_general}
c_j = \sqrt{\frac{g \lambda}{2 \pi} \tanh\left(\frac{2 \pi d}{\lambda}\right)}
\end{eqnarray}
%
But if the water depth is such that $d > \frac{\lambda}{2}$ we
can rewrite the phase velocity \ref{eq:laplace2D:c_general} as
%
\begin{eqnarray}
\label{eq:laplace2D:c_deep}
c_j^{deep} = \sqrt{\frac{g \lambda}{2 \pi}}
\end{eqnarray}
%
By definition the phase velocity can be also written as
$c_j = \omega_j / k_j$, so we can relate the wave length
with the period
%
\begin{eqnarray}
\label{eq:laplace2D:k_w}
k_j = \frac{\omega_j^2}{g}
\end{eqnarray}
%
Regarding the velocity potential, let us define it as
%
\begin{eqnarray}
\label{eq:laplace2D:incident_waves_potential}
\phi(x,z,t) = \sum_{j=1}^{n_{waves}} - \frac{a_j \omega_j}{k_j}
\cos\left(k_j x - \omega_j t + \delta_j \right)
\exp\left(k_j z\right)
\end{eqnarray}
%
such that
%
\begin{eqnarray*}
\begin{array}{rcl}
\dsty{\left. \frac{\partial \phi(x,z,t)}{\partial z} \right\vert_{z=0}} & = & v_z(x,t)
\\
\laplacian \phi(x,z,t) & = & 0
\end{array}
\end{eqnarray*}
%
This potential is valid for deep water waves if the exponent
$k_j z$ is small enough. $z$ can take values of the order of
$\mathcal{O}(a_j)$, so this method is valid for waves which
the length is such that
%
\begin{eqnarray*}
\lambda_j \gg 2 \pi a_j
\end{eqnarray*}
%
\section{BEM applied to Laplace 2D problem}
\label{ss:laplace2D:bem}
%
We have defined the sea waves outside from our computational domain
$\Omega$, where the waves can be perturbed by floating objects. In
the figure \ref{fig:ss:laplace2D:bem} a schematic view of the
computational domain is shown.\rc
%
The BEM is based in the reciprocal relation application
%
\begin{eqnarray}
\label{eq:laplace2D:reciprocal_relation}
\lambda(X, Z) \phi(X, Z; t) = \int_{\partial \Omega}
\phi(x, z; t) \frac{\partial G(x, z, X, Z)}{\partial \bs{n}(x, z)} -
G(x, z, X, Z) \frac{\partial \phi(x, z; t)}{\partial \bs{n}(x, z)}
\mbox{d} s(x, z)
\end{eqnarray}
%
Where
%
\begin{eqnarray*}
\lambda(X, Z) = \left\lbrace
\begin{array}{lcl}
1 & \mbox{if} & (X, Z) \in \Omega
\\
\frac{1}{2} & \mbox{if} & (X, Z) \in \partial \Omega
\\
0 & \mbox{if} & (X, Z) \not \in \Omega
\end{array}
\right.
\end{eqnarray*}
%
$G(x, z, X, Z)$ is the Green's function (a particular solution
of the Laplace equation), and the derivative respect to normal
denotes the gradient of the function projected over the normal.
%
\begin{eqnarray*}
\frac{\partial f(x, z)}{\partial \bs{n}(x, z)} =
\gradient f(x, z) \cdot \bs{n}(x, z)
\end{eqnarray*}
%
Hereinafter let we define the function $H(x, z, X, Z)$ as
%
\begin{eqnarray*}
H(x, z, X, Z) = \frac{\partial G(x, z, X, Z)}{\partial \bs{n}(x, z)}
\end{eqnarray*}
%
Therefore BEM allows to, knowing along the contour the potential or
the gradient, not both, compute the another one. The parts of the
contour where we know both potential and the gradient will enter in
the method as part of the independent term in the linear system of
equations.\rc
%
Since we know the potential out from the domain $\Omega$, we can know
the potential and the gradient along the inlet $\partial \Omega_{Inlet}$
and outlet $\partial \Omega_{Outlet}$.\rc
%
Regarding the bottom, we only can assert that the gradient along the
normal, that is the vertical velocity of the fluid, is null.\rc
%
Therefore, the inlet and outlet have relatively good properties because
we know all the data, so will not be additional work into the linear
system matrix that must be inverted, but the bottom don't have this
desirable property.\rc
%
Nevertheless, since the geometry of the inlet and
outlet is different from the free surface, and the bottom must be
explicitly considered, all the contour must be discretized with an
undesirable computational cost associated.\rc
%
So we are interested to know if we can replace our computational
domain $\Omega$ for other where only the free surface contour is
involved, moving the Inlet, the Outlet, and the bottom infinity far. We
could change our computational domain if the Green's function, and their
gradient, goes to zero as we go far enough. In 2D we can found a Green's
function for the Laplace problem such that
%
\begin{eqnarray}
\label{eq:laplace2D:g}
G(x, z, X, Z) = & \dsty{\frac{1}{4 \pi}} \log \left( \left(x - X\right)^2 + \left(z - Z\right)^2 \right)
\\
\label{eq:laplace2D:h}
H(x, z, X, Z) = & \dsty{\frac{1}{2 \pi}} \frac{\left( x - X, z - Z \right)}{\left( \left(x - X\right)^2 + \left(z - Z\right)^2 \right)}
\end{eqnarray}
%
Whose limits when the radius goes to infinite can be found
%
\begin{eqnarray}
\label{eq:laplace2D:limit_g}
\lim_{(x-X)^2 + (z-Z)^2 \to \infty} G(x, z, X, Z) = & \infty
\\
\label{eq:laplace2D:limit_h}
\lim_{(x-X)^2 + (z-Z)^2 \to \infty} H(x, z, X, Z) = & 0
\end{eqnarray}
%
So in the 2D Laplace problem, if we try to send the Inlet, the Outlet,
or the bottom to the infinite we can't use BEM because the Green's
function is not well defined, diverging with the distance.
%
\begin{figure}[ht!]
\centering
\includegraphics[width=0.4\textwidth]{Omega}
\caption{Computational domain $\Omega$}
\label{fig:ss:laplace2D:bem}
\end{figure}
%
\section{Conclusions to Laplace 2D problem}
\label{ss:laplace2D:conclusions}
%
We have briefly discussed the wave propagation problem using BEM in a 2D
case, seeing that in this case we need to consider all the contours,
including the Inlet, the Outlet, and the bottom. This approach is
successfully applied in a 2D problem in the reference \citep{vinayan2007}.
In 2D problem considering all the contours is not a heavy problem because
the number of nodes is usually small compared with a 3D case, but in a 3D
problem a computational less expensive method is required.\rc
%
We will not continue with the 2D Laplace problem because the solution will
not be useful for us in the 3D case.

View File

@ -0,0 +1,642 @@
\chapter{Waves propagations in 3D}
\label{s:laplace3D}
%
\section{General}
%
In this chapter the 3D case will be discussed, looking for
a method to solve the BEM using only the information about
the free surface.
%
This case is our main objective in order to can setup 6-DOF
seakeeping simulations.
%
\section{Incident waves}
%
We can rewrite the sea waves system outside from our
computational domain $\Omega$
%
\begin{eqnarray}
\label{eq:laplace3D:incident_waves}
\begin{array}{rcl}
z(x,y,t) & = & \dsty{\sum_{j=1}^{n_{waves}}} a_j \sin\left(k_j \left(x \cos(\beta) + y \sin(\beta)\right) - \omega_j t + \delta_j \right)
\\
v_z(x,y,t) & = & \dsty{\sum_{j=1}^{n_{waves}}} - a_j \omega_j \cos\left(k_j \left(x \cos(\beta) + y \sin(\beta)\right) - \omega_j t + \delta_j \right)
\\
\phi(x,z,t) & = & \dsty{\sum_{j=1}^{n_{waves}}} - \frac{a_j \omega_j}{k_j}
\cos\left(k_j \left(x \cos(\beta) + y \sin(\beta)\right) - \omega_j t + \delta_j \right)
\exp\left(k_j z\right)
\\
k_j & = & \dsty{\frac{\omega_j^2}{g}}
\end{array}
\end{eqnarray}
%
Where $\beta$ is the heading angle, being 0 for stern waves. For
this wave system still being valid the phase velocity from the
equation \ref{eq:laplace2D:c_deep}. The purposed potential is
compatible with the Laplace equation
\ref{eq:governing_equations:laplace} as well.
%
\section{BEM applied to Laplace 3D problem}
\label{ss:laplace3D:bem}
%
\subsection{Computational domain}
\label{sss:laplace3D:computational_domain}
%
We have a domain similar to the shown in the figure
\ref{fig:ss:laplace2D:bem}, but in this case 2 more boundaries
must be considered in the missed direction, that we will call
$\partial \Omega_{Front}$ and $\partial \Omega_{Back}$. As in
the 2D case we will apply the reciprocal relation
%
\begin{eqnarray}
\label{eq:laplace3D:reciprocal_relation}
\lambda(X, Y, Z) \phi(X, Y, Z; t) = \int_{\partial \Omega}
\phi(x, y, z; t) \frac{\partial G(x, y, z, X, Y, Z)}{\partial \bs{n}(x, y, z)} -
G(x, y, z, X, Y, Z) \frac{\partial \phi(x, y, z; t)}{\partial \bs{n}(x, y, z)}
\mbox{d} s(x, y, z)
\end{eqnarray}
%
We are focused into compute the gradient of the velocity
potential along the free surface knowing the velocity
potential value in each point one. Let we define the
function $H(x,y,z,X,Y,Z)$ again
%
\begin{eqnarray*}
H(x, y, z, X, Y, Z) = \frac{\partial G(x, y, z, X, Y, Z)}{\partial \bs{n}(x, y, z)}
\end{eqnarray*}
%
As in the Laplace equation for the 2D case, described in the
chapter \ref{s:laplace2D}, we want to expand the domain $\Omega$
such that all the boundaries except the free surface will the
infinity far, adding the boundary $\partial \Omega_{FS,I}$, where
we know the velocity potential and their gradient from
\ref{eq:laplace3D:incident_waves}. In the figure
\ref{fig:ss:laplace3D:bem} a schematic view of the expanded
domain can be seen.\rc
%
The main advantage is that, as happens with the Inlet and the
Outlet, we know all the needed data about the velocity potential,
so we can significantly reduce the linear system matrix dimensions,
and as happens with the bottom, the geometry is so quite similar
to the $\Omega_{FS}$ one, so no additional discretization or memory
storage is needed.\rc
%
This trick will only works if the Green's function $G(x,y,z,X,Y,Z)$,
and their gradient $H(x,y,z,X,Y,Z)$, goes to zero as $(x,y,z)$ goes
to infinite. In 3D Laplace problems we can use the following Green's
function:
%
\begin{eqnarray}
\label{eq:laplace3D:g}
G(x,y,z,X,Y,Z) = & \dsty{\frac{1}{\sqrt{\left(x - X\right)^2 + \left(y - Y\right)^2 + \left(z - Z\right)^2}}}
\\
\label{eq:laplace3D:h}
H(x,y,z,X,Y,Z) = & - \dsty{\frac{\left( x - X, y - Y, z - Z \right)}{\left(\left(x - X\right)^2 + \left(y - Y\right)^2 + \left(z - Z\right)^2\right)^{3/2}}}
\end{eqnarray}
%
That in the limit
%
\begin{eqnarray}
\label{eq:laplace3D:limit_g}
\lim_{(x-X)^2 + (y-Y)^2 + (z-Z)^2 \to \infty} G(x,y,z,X,Y,Z) = & 0
\\
\label{eq:laplace3D:limit_h}
\lim_{(x-X)^2 + (y-Y)^2 + (z-Z)^2 \to \infty} H(x,y,z,X,Y,Z) = & 0
\end{eqnarray}
%
So in this case, if the potential of the incidents waves is
a good function along all the free surface we can move from
the domain shown in the figure \ref{fig:ss:laplace2D:bem} to
the shown in the figure \ref{fig:ss:laplace3D:bem}, due to
along the other boundaries the Green's functions $G(x,y,z,X,Y,Z)$
and $H(x,y,z,X,Y,Z)$ are nulls, not computing in the equation
\ref{eq:laplace2D:reciprocal_relation}.
%
\begin{figure}[ht!]
\centering
\includegraphics[width=0.6\textwidth]{Omega2}
\caption{Computational domain $\Omega$}
\label{fig:ss:laplace3D:bem}
\end{figure}
%
\subsection{Boundary conditions (BC)}
\label{sss:laplace3D:BC}
%
In order to can purpose an evolution process we need to use
the boundary conditions along the free surface. In the most
general way we can rewrite the Bernoulli equation, that is
the dynamic free surface boundary condition (DFSBC), as (see
\citep{yang2004}):
%
\begin{eqnarray}
\label{eq:laplace3D:FS_Bernoulli}
\frac{\mbox{D} \phi(x,y,z;t)}{\mbox{D} t} =
\frac{1}{2}\left\vert \gradient \phi \right\vert^2
- g z(x,y;t)
- \frac{p_0}{\rho}
- \bs{U}(t) \cdot \gradient \phi(x,y,z;t)
- \frac{\partial \bs{U}(t)}{\partial t} \cdot (x,y,0)
\end{eqnarray}
%
Where $p_0$ is the atmospheric pressure, that we will consider
null, and $\bs{U}(t)$ is the ship velocity, in this case will be
a null vector. Since the material derivative denotes
%
\begin{eqnarray*}
\frac{\mbox{D} f}{\mbox{D} t} =
\frac{\partial f}{\partial t}
\gradient{\phi(x,y,z;t)} \cdot \gradient{f}
\end{eqnarray*}
%
We can rewrite the dynamic boundary condition for this specific case as
%
\begin{eqnarray}
\label{eq:laplace3D:DFSBC}
\frac{\partial \phi(x,y,z;t)}{\partial t} =
- \frac{1}{2}\left\vert \gradient \phi \right\vert^2
- g z(x,y;t)
\end{eqnarray}
%
Regarding the kinematic free surface boundary condition (KFSBC), in the
most general way we can write that
%
\begin{eqnarray}
\label{eq:laplace3D:FS_Kinematic}
\frac{\mbox{D} z(x,y;t)}{\mbox{D} t} =
\frac{\partial \phi(x,y,z;t)}{\partial z}
- \bs{U}(t) \cdot \gradient z(x,y;t)
\end{eqnarray}
%
Where we can expand the material derivative, writing the KFSBC for this
specific case
%
\begin{eqnarray}
\label{eq:laplace3D:KFSBC}
\frac{\partial z(x,y;t)}{\partial t} =
\frac{\partial \phi(x,y,z;t)}{\partial z}
- \gradient{\phi(x,y,z;t)} \cdot \gradient{z(x,y;t)}
\end{eqnarray}
%
\subsection{Time integration scheme}
\label{sss:laplace3D:TimeIntegration}
%
We may start the simulation in a initial condition where we know the
full free surface shape and velocity potential, including the gradients.
%
\begin{eqnarray}
\label{eq:laplace3D:IC}
\begin{array}{lcl}
z(x,y;t=0) & = & z_0(x,y)
\\
\phi(x,y,z;t=0) & = & \phi_0(x,y,z)
\\
\gradient z(x,y;t=0) & = & \gradient z_0(x,y)
\\
\gradient \phi(x,y,z;t=0) & = & \gradient \phi_0(x,y,z)
\end{array}
\end{eqnarray}
%
In the computational part of the free surface is enough to know the free
surface shape $z_0(x,y)$ and the velocity potential $\phi_0(x,y,z)$.\rc
%
For simplicity we will use an Euler's integration scheme, but the same
method can be easily applied for any other explicit time integrator, like
the Adams-Bashforth ones.\rc
%
In each time step we start knowing the shape of the free surface, and the
velocity potential, and basically we want to compute these fields for the
next time step. To do it the following steps are followed:
%
\begin{enumerate}
\item We use BEM to compute the velocity potential gradient, as will be
described in the section \ref{sss:laplace3D:bem_solve}.
\begin{eqnarray}
\label{eq:laplace3D:time_march:bem}
\gradient{\phi(x,y,z;t)} = \mbox{BEM}\left(\phi(x,y,z;t), z(x,y;t)\right)
\end{eqnarray}
\item We use the KFSBC to compute the derivative of the free surface
elevation, and the DFSBC to know the derivative of the velocity potential.
\begin{eqnarray}
\label{eq:laplace3D:time_march:dzdt}
\frac{\partial z(x,y;t)}{\partial t} = &
\mbox{KFSBC}\left(\gradient{\phi(x,y,z;t)}\right)
\\
\label{eq:laplace3D:time_march:dphidt}
\frac{\partial \phi(x,y,z;t)}{\partial t} = &
\mbox{DFSBC}\left(z(x,y;t), \gradient{\phi(x,y,z;t)}\right)
\end{eqnarray}
\item And then we can perform the time integration.
\begin{eqnarray}
\label{eq:laplace3D:time_march:z_integrate}
z(x,y;t + \Delta t) = &
z(x,y;t) +
\Delta t \dsty \frac{\partial z(x,y;t)}{\partial t}
\\
\label{eq:laplace3D:time_march:phi_integrate}
\phi(x,y,z;t + \Delta t) = &
\phi(x,y,z;t + \Delta t) +
\Delta t \dsty \frac{\partial \phi(x,y,z;t)}{\partial t}
\end{eqnarray}
\end{enumerate}
%
\subsection{Discrete Laplace solution using the BEM}
\label{sss:laplace3D:bem_solve}
%
As we have seen in the previous sections we want to use the BEM in order
to compute the velocity potential gradient in the free surface from the
velocity potential value known. In the equation
\ref{eq:laplace3D:reciprocal_relation} we can starting dividing the domain
contour as shown in the figure \ref{fig:ss:laplace3D:bem}, getting the
computational one, denoted by $\partial \Omega_{FS}$, and
the extension one, denoted by $\partial \Omega_{FS,I}$, where the free
surface and the velocity potential and gradient is known for all the
time instants.
%
\begin{eqnarray}
\label{eq:laplace3D:reciprocal_relation:002}
\begin{array}{l}
\frac{1}{2} \phi(X, Y, Z; t) =
\\
\dsty \int_{\partial \Omega_{FS}}
\phi(x, y, z; t) \frac{\partial G(x, y, z, X, Y, Z)}{\partial \bs{n}(x, y, z)} -
G(x, y, z, X, Y, Z) \frac{\partial \phi(x, y, z; t)}{\partial \bs{n}(x, y, z)}
\mbox{d} s(x, y, z)
\\
\dsty \int_{\partial \Omega_{FS,I}}
\phi(x, y, z; t) \frac{\partial G(x, y, z, X, Y, Z)}{\partial \bs{n}(x, y, z)} -
G(x, y, z, X, Y, Z) \frac{\partial \phi(x, y, z; t)}{\partial \bs{n}(x, y, z)}
\mbox{d} s(x, y, z)
\end{array}
\end{eqnarray}
%
Where we already assumed that $(x,y,z) \in \partial \Omega$. We can start discretizing
the velocity potential, assuming that the potential and their gradient changes smoothly
enough. The our contours can be divided according to the grid:
%
\begin{eqnarray}
\label{eq:laplace3D:reciprocal_relation:003}
\begin{array}{rl}
\frac{1}{2} \phi_a = &
\dsty \sum_{b=1}^{n_{FS}}
\phi_b
\dsty \int_{\partial \Omega_{FS}^b} H(\bs{x}, \bs{x}_a) \mbox{d} s(\bs{x})
-
\dsty \sum_{b=1}^{n_{FS}}
\frac{\partial \phi_b}{\partial \bs{n}_b}
\dsty \int_{\partial \Omega_{FS}^b} G(\bs{x}, \bs{x}_a) \mbox{d} s(\bs{x})
\\
&
\dsty \sum_{b=1}^{n_{FS,I}}
\phi_b
\dsty \int_{\partial \Omega_{FS,I}^b} H(\bs{x}, \bs{x}_a) \mbox{d} s(\bs{x})
-
\dsty \sum_{b=1}^{n_{FS,I}}
\frac{\partial \phi_b}{\partial \bs{n}_b}
\dsty \int_{\partial \Omega_{FS,I}^b} G(\bs{x}, \bs{x}_a) \mbox{d} s(\bs{x})
\end{array}
\end{eqnarray}
%
The functions $G(x,y,z,X,Y,Z)$ and $H(x,y,z,X,Y,Z)$, according to the equations
\ref{eq:laplace3D:g} and \ref{eq:laplace3D:h}, are well defined in all the
subintervals where $(x,y,z) \neq (X,Y,Z)$, and are so quite smooth, so we will
change all the integrals that accomplish it for point evaluations.
%
\begin{eqnarray}
\label{eq:laplace3D:reciprocal_relation:004}
\begin{array}{rl}
\frac{1}{2} \phi_a = &
\phi_a
\dsty \int_{\partial \Omega_{FS}^a} H(\bs{x}, \bs{x}_a) \mbox{d} s(\bs{x})
-
\frac{\partial \phi_a}{\partial \bs{n}_a}
\dsty \int_{\partial \Omega_{FS}^a} G(\bs{x}, \bs{x}_a) \mbox{d} s(\bs{x})
\\
&
\dsty \sum_{\substack{b = 1 \\ b \neq a}}^{n_{FS}}
\left(
\phi_b H_{ba} - \frac{\partial \phi_b}{\partial \bs{n}_b} G_{ba}
\right) S_b
+
\dsty \sum_{b=1}^{n_{FS,I}}
\left(
\phi_b H_{ba} - \frac{\partial \phi_b}{\partial \bs{n}_b} G_{ba}
\right) S_b
\end{array}
\end{eqnarray}
%
The remaining integrals must be treated carefully since the functions are
singular in the center of the interval. $H(x,y,z,X,Y,Z)$ is an odd function,
so the limit of the integral when the radius of the interval goes to zero
is null, being well defined. Regarding the function $G(x,y,z,X,Y,Z)$ is an
even function of order:
%
\begin{eqnarray*}
G(\bs{x},\bs{x_a}) = \mathcal{O}\left(\frac{1}{\vert \bs{x} - \bs{x_a}\vert}\right)
\end{eqnarray*}
%
Which their integral is defined if the function $z(x,y)$ is well defined
as well. So the remaining integrals can be numerically computed, being mindful
that:
%
\begin{enumerate}
\item Can't be evaluated at the point $\bs{x_a}$.
\item Changes too fast around the point $\bs{x_a}$.
\end{enumerate}
%
We will discuss later how to solve this integrals, for the moment we will define
new functions such that:
%
\begin{eqnarray}
\label{eq:laplace3D:g:hat}
\hat G_{ab} =
\left\lbrace \begin{array}{l}
\dsty \int_{\partial \Omega_{FS}^a} G(\bs{x}, \bs{x}_a) \mbox{d} s(\bs{x}); \, \, \mbox{if} \, a = b
\\
G(\bs{x_b},\bs{x_a}) S_b; \, \, \mbox{if} \, a \neq b
\end{array} \right.
\\
\label{eq:laplace3D:h:hat}
\hat H_{ab} =
\left\lbrace \begin{array}{l}
\dsty \int_{\partial \Omega_{FS}^a} H(\bs{x}, \bs{x}_a) \mbox{d} s(\bs{x}); \, \, \mbox{if} \, a = b
\\
H(\bs{x_b},\bs{x_a}) S_b; \, \, \mbox{if} \, a \neq b
\end{array} \right.
\end{eqnarray}
%
So we can rewrite the equation \ref{eq:laplace3D:reciprocal_relation:004}
%
\begin{eqnarray}
\label{eq:laplace3D:reciprocal_relation:005}
\frac{1}{2} \phi_a
=
\dsty \sum_{b=1}^{n_{FS}}
\left(
\phi_b \hat H_{ba} - \frac{\partial \phi_b}{\partial \bs{n}_b} \hat G_{ba}
\right)
+
\dsty \sum_{b=1}^{n_{FS,I}}
\left(
\phi_b \hat H_{ba} - \frac{\partial \phi_b}{\partial \bs{n}_b} \hat G_{ba}
\right)
\end{eqnarray}
%
Where we can move all the terms of the computational free surface that affects
to the gradient of the velocity potential (that is the value that we want to
compute) to left hand side, and let all the other ones in the right hand side
of the equation
%
\begin{eqnarray}
\label{eq:laplace3D:reciprocal_relation:006}
\dsty \sum_{b \in \partial \Omega_{FS}}
\frac{\partial \phi_b}{\partial \bs{n}_b} \hat G_{ba}
=
-
\frac{1}{2} \phi_a
+
\dsty \sum_{b \in \partial \Omega_{FS}}
\phi_b \hat H_{ba}
+
\dsty \sum_{b \in \partial \Omega_{FS,I}}
\left(
\phi_b \hat H_{ba} -
\frac{\partial \phi_b}{\partial \bs{n}_b} \hat G_{ba}
\right)
\end{eqnarray}
%
The equation \ref{eq:laplace3D:reciprocal_relation:006}, that
has been written for the velocity potential at one point $\bs{x}_a$,
can be written for all the points of the free surface along
the computational domain using the matrix notation
%
\begin{eqnarray}
\label{eq:laplace3D:reciprocal_relation:007}
\mathcal{G} \left[ \frac{ \partial \phi}{\partial \bs{n}} \right]
=
\left( \mathcal{H} - \frac{1}{2} \mathcal{I} \right) \left[ \phi \right]
+
\mathcal{H}_{FS,I} \left[ \phi \right]_{FS,I}
-
\mathcal{G}_{FS,I} \left[ \frac{ \partial \phi}{\partial \bs{n}} \right]_{FS,I}
\end{eqnarray}
%
Note that the area of the elements $S_b$ has been included into
the matrices. The equation
\ref{eq:laplace3D:reciprocal_relation:007} is a linear system
of equations that can be numerically solved, either inverting
the matrix, or using an iterative method. The matrix inversion
is probably the best way for linear seakeeping codes, where the
same matrix will be ever used, but in this case the iterative
method is the faster way.\rc
%
The method described along this section allows to us to compute
the gradient of the velocity potential along the free surface
knowing the potential in the computational free surface, and both
velocity potential and the gradient along the extended free
surface.
%
\subsection{Integrals computation}
\label{sss:laplace3D:integrals}
%
In the equations \ref{eq:laplace3D:g:hat} and \ref{eq:laplace3D:g:hat}
we have introduced two inconvenient integrals. Even though the functions
are not well defined when $\bs{x} = \bs{x_a}$, their integrals it is.
For instance, if we can assume that the free surface is fully planar
($z = 0$), the integrals can be analytically computed
%
\begin{eqnarray*}
\dsty \int_{y_a - \delta y}^{y_a + \delta y} \int_{x_a - \delta x}^{x_a + \delta x}
G(x,y,0,x_a,y_a,0)
\, \mbox{d}x \, \mbox{d}y
= &
\dsty \frac{
\delta x \, \, \mbox{asinh}\left(\frac{\delta y}{\delta x}\right)
+
\delta y \, \, \mbox{asinh}\left(\frac{\delta x}{\delta y}\right)
}{\pi}
\\
\dsty \int_{y_a - \delta y}^{y_a + \delta y} \int_{x_a - \delta x}^{x_a + \delta x}
H(x,y,0,x_a,y_a,0)
\, \mbox{d}x \, \mbox{d}y
= &
0
\end{eqnarray*}
%
But can not be analytically computed for every function $z(x,y)$, being
necessary to compute it in a numerical way.\rc
%
In the figure \ref{fig:ss:laplace3D:integral} a schematic representation
of the integration method is shown. Let we want to compute the integral
for an element of the grid $(x_a,y_a)$, then we subdivide the element in
\textbf{a even number} of subelements of area $dx \cdot dy$, so we can
assert that any subelement will be evaluated in the point $(x_a,y_a)$,
but as near as we want because we can ever add more subelements; then we
can numerically approximate the integral by (here in after we will use
only the function $G(\bs{x}, bs{x_a})$, because same method can be applied
to the function $H(\bs{x}, bs{x_a})$).
%
\begin{eqnarray}
\label{eq:laplace3D:integral:g}
\dsty \int_{\partial \Omega_{FS}^a} G(\bs{x}, \bs{x}_a) \mbox{d} s(\bs{x})
\simeq
\sum_{i=1}^{n_x} \sum_{j=1}^{n_y} G(x_i,y_j,z(x_i,y_i), x_a, y_a, z(x_a, y_a)) \, dx \, dy
\end{eqnarray}
%
Of course the value $z(x_a, y_a)$ is known, but not the function $z(x_i,y_i)$
because is evaluated in points that are not reflected in the grid, so we must
compute this points from the available data. We will start renormalizing the
coordinates such that:
%
\begin{eqnarray}
\label{eq:laplace3D:integral:uv}
\begin{array}{lcl}
u & = & \dsty \frac{x - \left(x_a - Dx\right)}{2 Dx}
\\
v & = & \dsty \frac{y - \left(y_a - Dy\right)}{2 Dy}
\end{array}
\end{eqnarray}
%
So we know the value of $z$ for all the combinations of $u = 0,0.5,1$ and
$v = 0,0.5,1$. Then, to can evaluate the function $z(u,v)$ for all $u,v$
values we may to build a Spline surface with the data known from the 9
points shown in the figure \ref{fig:ss:laplace3D:integral}. The Spline
surface can be characterized as
%
\begin{eqnarray}
\label{eq:laplace3D:integral:spline}
z(u,v) = k_0 + k_u u + k_v v + k_{uv} u v + k_{uu} u^2 + k_{vv} v^2
+ k_{uuv} u^2 v + k_{uvv} u v^2 + k_{uuvv} u^2 v^2
\end{eqnarray}
%
In the equation \ref{eq:laplace3D:integral:spline} we have 9 unknown
coefficients, but we have available $z(u,v)$ for 9 points, so have 9
unknowns with 9 equations that can be set as a linear system of
equations, that results in the following coefficients:
%
\begin{eqnarray}
\label{eq:laplace3D:integral:k}
\begin{array}{lcl}
k_0 & = & z \left( 0,0 \right)
\\
k_u & = & - z \left( 1,0 \right) + 4 z \left( \frac{1}{2},0 \right) - 3 z \left( 0,0 \right)
\\
k_v & = & - z \left( 0,1 \right) + 4 z \left( 0,\frac{1}{2} \right) - 3 z \left( 0,0 \right)
\\
k_{uv} & = & z \left( 1,1 \right) - 4 z \left( 1,\frac{1}{2} \right) + 3 z \left( 1,0 \right)
- 4 z \left( \frac{1}{2},1 \right) + 16 z \left( \frac{1}{2},\frac{1}{2} \right)
\\ & &
- 12 z \left( \frac{1}{2},0 \right) + 3 z \left( 0,1 \right)
- 12 z \left( 0,\frac{1}{2} \right) + 9 z \left( 0,0 \right)
\\
k_{uu} & = & 2 z \left( 1,0 \right) - 4 z \left( \frac{1}{2},0 \right) + 2 z \left( 1,0 \right)
\\
k_{vv} & = & 2 z \left( 0,1 \right) - 4 z \left( 0,\frac{1}{2} \right) + 2 z \left( 1,0 \right)
\\
k_{uuv} & = & - 2 z \left( 1,1 \right) + 8 z \left( 1,\frac{1}{2} \right) - 6 z \left( 1,0 \right)
+ 4 z \left( \frac{1}{2},1 \right) - 16 z \left( \frac{1}{2},\frac{1}{2} \right)
\\ & &
+ 12 z \left( \frac{1}{2},0 \right) - 2 z \left( 0,1 \right)
+ 8 z \left( 0,\frac{1}{2} \right) - 6 z \left( 0,0 \right)
\\
k_{uvv} & = & - 2 z \left( 1,1 \right) + 4 z \left( 1,\frac{1}{2} \right) - 2 z \left( 1,0 \right)
+ 8 z \left( \frac{1}{2},1 \right) - 16 z \left( \frac{1}{2},\frac{1}{2} \right)
\\ & &
+ 8 z \left( \frac{1}{2},0 \right) - 6 z \left( 0,1 \right)
+ 12 z \left( 0,\frac{1}{2} \right) - 6 z \left( 0,0 \right)
\\
k_{uuvv} & = & 4 z \left( 1,1 \right) - 8 z \left( 1,\frac{1}{2} \right) + 4 z \left( 1,0 \right)
- 8 z \left( \frac{1}{2},1 \right) + 16 z \left( \frac{1}{2},\frac{1}{2} \right)
\\ & &
- 8 z \left( \frac{1}{2},0 \right) + 4 z \left( 0,1 \right)
- 8 z \left( 0,\frac{1}{2} \right) + 4 z \left( 0,0 \right)
\end{array}
\end{eqnarray}
%
So using the equation \ref{eq:laplace3D:integral:g} to \ref{eq:laplace3D:integral:k}
we can compute the integrals in the equations \ref{eq:laplace3D:g:hat} and
\ref{eq:laplace3D:h:hat}.
%
\begin{figure}[ht!]
\centering
\includegraphics[width=0.6\textwidth]{Integral}
\caption{Integration method scheme}
\label{fig:ss:laplace3D:integral}
\end{figure}
%
\section{BEM test}
\label{ss:laplace3D:test}
%
\subsection{General}
\label{sss:laplace3D:test:general}
%
A Python script has been provided with this document in the subfolder \textbf{test}.
In the script all this theory is tested in order to know if the BEM is well purposed,
and the errors that can be expected from the method application.\rc
%
In the test, for the moment, only one wave will be set, and the computational free
surface will be big enough to contain 2 wave lengths. In this case a wave period
of $T = 2.5 s$ is used, resulting in a wave of 10 meters.\rc
%
In the figure \ref{fig:laplace3D:test:wave} the wave used, that runs in the x direction,
is shown. The free surface will be extended while $G(x,y,z,X,Y,Z) > 0.1$.
%
\begin{figure}[ht!]
\centering
\includegraphics[width=0.6\textwidth]{test_wave}
\caption{Wave used in the test}
\label{fig:laplace3D:test:wave}
\end{figure}
%
\subsection{Direct method}
\label{sss:laplace3D:test:direct}
%
The direct method consist in evaluate the velocity potential in several points
using the equation \ref{eq:laplace3D:reciprocal_relation:005}, testing the error
get.\rc
%
If we apply the direct method for all the points of the computational free surface,
we can compute the root mean square error as
%
\begin{eqnarray*}
RMS(nx,ny) = \sqrt{\frac{1}{nx \, ny} \sum_{i=1}^{nx} \sum_{j=1}^{ny}
\left( \phi_{direct}(x_i,y_j) - \phi(x_i,y_j) \right)^2
}
\end{eqnarray*}
%
For $nx = 31$ and $ny = 15$ we have $RMS(31,15) = 0.08$. In the figure
\ref{fig:laplace3D:test:direct} the analytic velocity potential, and the
interpolated using the direct method, for a slice in the middle of the
free surface ($y=0$).\rc
%
The results quality is good, and can be improved increasing the number of
points in the computational free surface.
%
\begin{figure}[ht!]
\centering
\includegraphics[width=0.6\textwidth]{test_direct}
\caption{Direct method}
\label{fig:laplace3D:test:direct}
\end{figure}
%
\subsection{BEM}
\label{sss:laplace3D:test:bem}
%
In this case we want to apply the equation \ref{eq:laplace3D:reciprocal_relation:006},
where a linear system of equations is purposed in order to compute the gradient of the
velocity potential, projected over the normal, for all the points of the grid.
%
For $nx = 31$ and $ny = 15$ we have $RMS(31,15) = 0.04$. In the figure
\ref{fig:laplace3D:test:bem} the analytic velocity potential, and the
interpolated using the direct method, for a slice in the middle of the
free surface ($y=0$).\rc
%
The results quality is nice like in the direct method. In order to get enough good
results at least 15 points per wave length must be used (like in this application).
%
\begin{figure}[ht!]
\centering
\includegraphics[width=0.6\textwidth]{test_bem}
\caption{BEM solution}
\label{fig:laplace3D:test:bem}
\end{figure}
%

View File

@ -0,0 +1,125 @@
\relax
\bibstyle{plainnat}
\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument}
\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined
\global\let\oldcontentsline\contentsline
\gdef\contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}}
\global\let\oldnewlabel\newlabel
\gdef\newlabel#1#2{\newlabelxx{#1}#2}
\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}}
\AtEndDocument{\ifx\hyper@anchor\@undefined
\let\contentsline\oldcontentsline
\let\newlabel\oldnewlabel
\fi}
\fi}
\global\let\hyper@last\relax
\gdef\HyperFirstAtBeginDocument#1{#1}
\providecommand\HyField@AuxAddToFields[1]{}
\citation{bem_2007}
\citation{vinayan2007}
\@writefile{toc}{\contentsline {chapter}{\numberline {1}Introduction}{5}{chapter.1}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\newlabel{s:introduction}{{1}{5}{Introduction\relax }{chapter.1}{}}
\@writefile{toc}{\contentsline {section}{\numberline {1.1}Objective}{5}{section.1.1}}
\citation{bem_2007}
\@writefile{toc}{\contentsline {chapter}{\numberline {2}Governing equations}{7}{chapter.2}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\newlabel{s:governing_equations}{{2}{7}{Governing equations\relax }{chapter.2}{}}
\newlabel{eq:governing_equations:v_potential}{{2.2}{7}{Governing equations\relax }{equation.2.0.2}{}}
\newlabel{eq:governing_equations:laplace}{{2.3}{7}{Governing equations\relax }{equation.2.0.3}{}}
\newlabel{eq:governing_equations:bernoulli}{{2.4}{7}{Governing equations\relax }{equation.2.0.3}{}}
\@writefile{toc}{\contentsline {chapter}{\numberline {3}Waves propagations in 2D plane}{9}{chapter.3}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\newlabel{s:laplace2D}{{3}{9}{Waves propagations in 2D plane\relax }{chapter.3}{}}
\@writefile{toc}{\contentsline {section}{\numberline {3.1}General}{9}{section.3.1}}
\@writefile{toc}{\contentsline {section}{\numberline {3.2}Incident waves}{9}{section.3.2}}
\newlabel{eq:laplace2D:incident_waves}{{3.1}{9}{Incident waves\relax }{equation.3.2.1}{}}
\newlabel{eq:laplace2D:c_general}{{3.2}{9}{Incident waves\relax }{equation.3.2.2}{}}
\newlabel{eq:laplace2D:c_deep}{{3.3}{9}{Incident waves\relax }{equation.3.2.3}{}}
\newlabel{eq:laplace2D:k_w}{{3.4}{9}{Incident waves\relax }{equation.3.2.4}{}}
\newlabel{eq:laplace2D:incident_waves_potential}{{3.5}{9}{Incident waves\relax }{equation.3.2.5}{}}
\@writefile{toc}{\contentsline {section}{\numberline {3.3}BEM applied to Laplace 2D problem}{10}{section.3.3}}
\newlabel{ss:laplace2D:bem}{{3.3}{10}{BEM applied to Laplace 2D problem\relax }{section.3.3}{}}
\newlabel{eq:laplace2D:reciprocal_relation}{{3.6}{10}{BEM applied to Laplace 2D problem\relax }{equation.3.3.6}{}}
\citation{vinayan2007}
\newlabel{eq:laplace2D:g}{{3.7}{11}{BEM applied to Laplace 2D problem\relax }{equation.3.3.7}{}}
\newlabel{eq:laplace2D:h}{{3.8}{11}{BEM applied to Laplace 2D problem\relax }{equation.3.3.7}{}}
\newlabel{eq:laplace2D:limit_g}{{3.9}{11}{BEM applied to Laplace 2D problem\relax }{equation.3.3.9}{}}
\newlabel{eq:laplace2D:limit_h}{{3.10}{11}{BEM applied to Laplace 2D problem\relax }{equation.3.3.9}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {3.1}{\ignorespaces Computational domain $\Omega $}}{11}{figure.3.1}}
\newlabel{fig:ss:laplace2D:bem}{{3.1}{11}{Computational domain $\Omega $\relax }{figure.3.1}{}}
\@writefile{toc}{\contentsline {section}{\numberline {3.4}Conclusions to Laplace 2D problem}{11}{section.3.4}}
\newlabel{ss:laplace2D:conclusions}{{3.4}{11}{Conclusions to Laplace 2D problem\relax }{section.3.4}{}}
\@writefile{toc}{\contentsline {chapter}{\numberline {4}Waves propagations in 3D}{13}{chapter.4}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\newlabel{s:laplace3D}{{4}{13}{Waves propagations in 3D\relax }{chapter.4}{}}
\@writefile{toc}{\contentsline {section}{\numberline {4.1}General}{13}{section.4.1}}
\@writefile{toc}{\contentsline {section}{\numberline {4.2}Incident waves}{13}{section.4.2}}
\newlabel{eq:laplace3D:incident_waves}{{4.1}{13}{Incident waves\relax }{equation.4.2.1}{}}
\@writefile{toc}{\contentsline {section}{\numberline {4.3}BEM applied to Laplace 3D problem}{13}{section.4.3}}
\newlabel{ss:laplace3D:bem}{{4.3}{13}{BEM applied to Laplace 3D problem\relax }{section.4.3}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.1}Computational domain}{13}{subsection.4.3.1}}
\newlabel{sss:laplace3D:computational_domain}{{4.3.1}{13}{Computational domain\relax }{subsection.4.3.1}{}}
\newlabel{eq:laplace3D:reciprocal_relation}{{4.2}{13}{Computational domain\relax }{equation.4.3.2}{}}
\citation{yang2004}
\newlabel{eq:laplace3D:g}{{4.3}{14}{Computational domain\relax }{equation.4.3.3}{}}
\newlabel{eq:laplace3D:h}{{4.4}{14}{Computational domain\relax }{equation.4.3.3}{}}
\newlabel{eq:laplace3D:limit_g}{{4.5}{14}{Computational domain\relax }{equation.4.3.5}{}}
\newlabel{eq:laplace3D:limit_h}{{4.6}{14}{Computational domain\relax }{equation.4.3.5}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {4.1}{\ignorespaces Computational domain $\Omega $}}{14}{figure.4.1}}
\newlabel{fig:ss:laplace3D:bem}{{4.1}{14}{Computational domain $\Omega $\relax }{figure.4.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.2}Boundary conditions (BC)}{14}{subsection.4.3.2}}
\newlabel{sss:laplace3D:BC}{{4.3.2}{14}{Boundary conditions (BC)\relax }{subsection.4.3.2}{}}
\newlabel{eq:laplace3D:FS_Bernoulli}{{4.7}{14}{Boundary conditions (BC)\relax }{equation.4.3.7}{}}
\newlabel{eq:laplace3D:DFSBC}{{4.8}{15}{Boundary conditions (BC)\relax }{equation.4.3.8}{}}
\newlabel{eq:laplace3D:FS_Kinematic}{{4.9}{15}{Boundary conditions (BC)\relax }{equation.4.3.9}{}}
\newlabel{eq:laplace3D:KFSBC}{{4.10}{15}{Boundary conditions (BC)\relax }{equation.4.3.10}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.3}Time integration scheme}{15}{subsection.4.3.3}}
\newlabel{sss:laplace3D:TimeIntegration}{{4.3.3}{15}{Time integration scheme\relax }{subsection.4.3.3}{}}
\newlabel{eq:laplace3D:IC}{{4.11}{15}{Time integration scheme\relax }{equation.4.3.11}{}}
\newlabel{eq:laplace3D:time_march:bem}{{4.12}{15}{Time integration scheme\relax }{equation.4.3.12}{}}
\newlabel{eq:laplace3D:time_march:dzdt}{{4.13}{15}{Time integration scheme\relax }{equation.4.3.13}{}}
\newlabel{eq:laplace3D:time_march:dphidt}{{4.14}{15}{Time integration scheme\relax }{equation.4.3.13}{}}
\newlabel{eq:laplace3D:time_march:z_integrate}{{4.15}{15}{Time integration scheme\relax }{equation.4.3.15}{}}
\newlabel{eq:laplace3D:time_march:phi_integrate}{{4.16}{15}{Time integration scheme\relax }{equation.4.3.15}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.4}Discrete Laplace solution using the BEM}{16}{subsection.4.3.4}}
\newlabel{sss:laplace3D:bem_solve}{{4.3.4}{16}{Discrete Laplace solution using the BEM\relax }{subsection.4.3.4}{}}
\newlabel{eq:laplace3D:reciprocal_relation:002}{{4.17}{16}{Discrete Laplace solution using the BEM\relax }{equation.4.3.17}{}}
\newlabel{eq:laplace3D:reciprocal_relation:003}{{4.18}{16}{Discrete Laplace solution using the BEM\relax }{equation.4.3.18}{}}
\newlabel{eq:laplace3D:reciprocal_relation:004}{{4.19}{16}{Discrete Laplace solution using the BEM\relax }{equation.4.3.19}{}}
\newlabel{eq:laplace3D:g:hat}{{4.20}{16}{Discrete Laplace solution using the BEM\relax }{equation.4.3.20}{}}
\newlabel{eq:laplace3D:h:hat}{{4.21}{16}{Discrete Laplace solution using the BEM\relax }{equation.4.3.20}{}}
\newlabel{eq:laplace3D:reciprocal_relation:005}{{4.22}{17}{Discrete Laplace solution using the BEM\relax }{equation.4.3.22}{}}
\newlabel{eq:laplace3D:reciprocal_relation:006}{{4.23}{17}{Discrete Laplace solution using the BEM\relax }{equation.4.3.23}{}}
\newlabel{eq:laplace3D:reciprocal_relation:007}{{4.24}{17}{Discrete Laplace solution using the BEM\relax }{equation.4.3.24}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3.5}Integrals computation}{17}{subsection.4.3.5}}
\newlabel{sss:laplace3D:integrals}{{4.3.5}{17}{Integrals computation\relax }{subsection.4.3.5}{}}
\newlabel{eq:laplace3D:integral:g}{{4.25}{17}{Integrals computation\relax }{equation.4.3.25}{}}
\newlabel{eq:laplace3D:integral:uv}{{4.26}{18}{Integrals computation\relax }{equation.4.3.26}{}}
\newlabel{eq:laplace3D:integral:spline}{{4.27}{18}{Integrals computation\relax }{equation.4.3.27}{}}
\newlabel{eq:laplace3D:integral:k}{{4.28}{18}{Integrals computation\relax }{equation.4.3.28}{}}
\@writefile{toc}{\contentsline {section}{\numberline {4.4}BEM test}{18}{section.4.4}}
\newlabel{ss:laplace3D:test}{{4.4}{18}{BEM test\relax }{section.4.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.1}General}{18}{subsection.4.4.1}}
\newlabel{sss:laplace3D:test:general}{{4.4.1}{18}{General\relax }{subsection.4.4.1}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {4.2}{\ignorespaces Integration method scheme}}{19}{figure.4.2}}
\newlabel{fig:ss:laplace3D:integral}{{4.2}{19}{Integration method scheme\relax }{figure.4.2}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {4.3}{\ignorespaces Wave used in the test}}{19}{figure.4.3}}
\newlabel{fig:laplace3D:test:wave}{{4.3}{19}{Wave used in the test\relax }{figure.4.3}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.2}Direct method}{19}{subsection.4.4.2}}
\newlabel{sss:laplace3D:test:direct}{{4.4.2}{19}{Direct method\relax }{subsection.4.4.2}{}}
\bibdata{bib}
\@writefile{lof}{\contentsline {figure}{\numberline {4.4}{\ignorespaces Direct method}}{20}{figure.4.4}}
\newlabel{fig:laplace3D:test:direct}{{4.4}{20}{Direct method\relax }{figure.4.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4.3}BEM}{20}{subsection.4.4.3}}
\newlabel{sss:laplace3D:test:bem}{{4.4.3}{20}{BEM\relax }{subsection.4.4.3}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {4.5}{\ignorespaces BEM solution}}{21}{figure.4.5}}
\newlabel{fig:laplace3D:test:bem}{{4.5}{21}{BEM solution\relax }{figure.4.5}{}}
\bibcite{bem_2007}{{1}{2007}{{Ang}}{{}}}
\bibcite{vinayan2007}{{2}{2007}{{Vinayan and Kinnas}}{{}}}
\bibcite{yang2004}{{3}{2004}{{Yang}}{{}}}
\@writefile{toc}{\contentsline {chapter}{Bibliography}{23}{chapter*.2}}

View File

@ -0,0 +1,24 @@
\begin{thebibliography}{3}
\providecommand{\natexlab}[1]{#1}
\providecommand{\url}[1]{\texttt{#1}}
\expandafter\ifx\csname urlstyle\endcsname\relax
\providecommand{\doi}[1]{doi: #1}\else
\providecommand{\doi}{doi: \begingroup \urlstyle{rm}\Url}\fi
\bibitem[Ang(2007)]{bem_2007}
Whye-Teong Ang.
\newblock \emph{A Beginners Course in Boundary Element Methods}.
\newblock Cambridge University Press, New York, 2007.
\bibitem[Vinayan and Kinnas(2007)]{vinayan2007}
V.~Vinayan and S.~A. Kinnas.
\newblock A bem for the propagation of nonlinear planar free-surface waves.
\newblock \emph{Electronic Journal of Boundary Elements}, 5:\penalty0 17--40,
2007.
\bibitem[Yang(2004)]{yang2004}
Jinghai Yang.
\newblock \emph{Time domain, nonlinear theories on ship motions}.
\newblock PhD thesis, University of Hawaii, 2004.
\end{thebibliography}

View File

@ -0,0 +1,48 @@
This is BibTeX, Version 0.99d (TeX Live 2012/Debian)
Capacity: max_strings=35307, hash_size=35307, hash_prime=30011
The top-level auxiliary file: main.aux
The style file: plainnat.bst
Database file #1: bib.bib
Warning--can't use both author and editor fields in bem_2007
You've used 3 entries,
2773 wiz_defined-function locations,
726 strings with 6674 characters,
and the built_in function-call counts, 1030 in all, are:
= -- 88
> -- 41
< -- 3
+ -- 15
- -- 12
* -- 67
:= -- 173
add.period$ -- 9
call.type$ -- 3
change.case$ -- 11
chr.to.int$ -- 3
cite$ -- 7
duplicate$ -- 56
empty$ -- 92
format.name$ -- 17
if$ -- 207
int.to.chr$ -- 1
int.to.str$ -- 1
missing$ -- 3
newline$ -- 23
num.names$ -- 12
pop$ -- 25
preamble$ -- 1
purify$ -- 10
quote$ -- 0
skip$ -- 41
stack$ -- 0
substring$ -- 21
swap$ -- 4
text.length$ -- 0
text.prefix$ -- 0
top$ -- 0
type$ -- 28
warning$ -- 1
while$ -- 10
width$ -- 0
write$ -- 45
(There was 1 warning)

View File

@ -0,0 +1,827 @@
This is pdfTeX, Version 3.1415926-2.4-1.40.13 (TeX Live 2012/Debian) (format=pdflatex 2012.12.24) 1 APR 2013 19:55
entering extended mode
restricted \write18 enabled.
%&-line parsing enabled.
**main.tex
(./main.tex
LaTeX2e <2011/06/27>
Babel <v3.8m> and hyphenation patterns for english, dumylang, nohyphenation, lo
aded.
(/usr/share/texlive/texmf-dist/tex/latex/base/book.cls
Document Class: book 2007/10/19 v1.4h Standard LaTeX document class
(/usr/share/texlive/texmf-dist/tex/latex/base/bk12.clo
File: bk12.clo 2007/10/19 v1.4h Standard LaTeX file (size option)
)
\c@part=\count79
\c@chapter=\count80
\c@section=\count81
\c@subsection=\count82
\c@subsubsection=\count83
\c@paragraph=\count84
\c@subparagraph=\count85
\c@figure=\count86
\c@table=\count87
\abovecaptionskip=\skip41
\belowcaptionskip=\skip42
\bibindent=\dimen102
)
(/usr/share/texlive/texmf-dist/tex/latex/natbib/natbib.sty
Package: natbib 2010/09/13 8.31b (PWD, AO)
\bibhang=\skip43
\bibsep=\skip44
LaTeX Info: Redefining \cite on input line 694.
\c@NAT@ctr=\count88
)
(/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty
Package: graphicx 1999/02/16 v1.0f Enhanced LaTeX Graphics (DPC,SPQR)
(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty
Package: keyval 1999/03/16 v1.13 key=value parser (DPC)
\KV@toks@=\toks14
)
(/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty
Package: graphics 2009/02/05 v1.0o Standard LaTeX Graphics (DPC,SPQR)
(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty
Package: trig 1999/03/16 v1.09 sin cos tan (DPC)
)
(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg
File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live
)
Package graphics Info: Driver file: pdftex.def on input line 91.
(/usr/share/texlive/texmf-dist/tex/latex/pdftex-def/pdftex.def
File: pdftex.def 2011/05/27 v0.06d Graphics/color for pdfTeX
(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty
Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO)
)
(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty
Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO)
)
\Gread@gobject=\count89
))
\Gin@req@height=\dimen103
\Gin@req@width=\dimen104
)
(/usr/share/texlive/texmf-dist/tex/latex/tools/verbatim.sty
Package: verbatim 2003/08/22 v1.5q LaTeX2e package for verbatim enhancements
\every@verbatim=\toks15
\verbatim@line=\toks16
\verbatim@in@stream=\read1
)
(/usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty
Package: color 2005/11/14 v1.0j Standard LaTeX Color (DPC)
(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg
File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive
)
Package color Info: Driver file: pdftex.def on input line 130.
)
(/usr/share/texlive/texmf-dist/tex/latex/colortbl/colortbl.sty
Package: colortbl 2012/02/13 v1.0a Color table columns (DPC)
(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty
Package: array 2008/09/09 v2.4c Tabular extension package (FMi)
\col@sep=\dimen105
\extrarowheight=\dimen106
\NC@list=\toks17
\extratabsurround=\skip45
\backup@length=\skip46
)
\everycr=\toks18
\minrowclearance=\skip47
)
(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty
Package: hyperref 2012/05/13 v6.82q Hypertext links for LaTeX
(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty
Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO)
(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty
Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO)
Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO)
Package hobsub Info: Skipping package `infwarerr' (already loaded).
Package hobsub Info: Skipping package `ltxcmds' (already loaded).
Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO)
Package ifluatex Info: LuaTeX not detected.
Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO)
Package ifvtex Info: VTeX not detected.
Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO)
Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO)
Package ifpdf Info: pdfTeX in PDF mode is detected.
Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO)
Package etexcmds Info: Could not find \expanded.
(etexcmds) That can mean that you are not using pdfTeX 1.50 or
(etexcmds) that some package has redefined \expanded.
(etexcmds) In the latter case, load this package earlier.
Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO)
Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO)
Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO
)
Package pdftexcmds Info: LuaTeX not detected.
Package pdftexcmds Info: \pdf@primitive is available.
Package pdftexcmds Info: \pdf@ifprimitive is available.
Package pdftexcmds Info: \pdfdraftmode found.
Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO)
Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO
)
Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO)
Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO)
)
Package hobsub Info: Skipping package `hobsub' (already loaded).
Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO)
Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO)
Package: xcolor-patch 2011/01/30 xcolor patch
Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO)
Package atveryend Info: \enddocument detected (standard20110627).
Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO)
Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO)
Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO)
)
(/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty
Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional
)
(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty
Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO)
)
\@linkdim=\dimen107
\Hy@linkcounter=\count90
\Hy@pagecounter=\count91
(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def
File: pd1enc.def 2012/05/13 v6.82q Hyperref: PDFDocEncoding definition (HO)
)
\Hy@SavedSpaceFactor=\count92
(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg
File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive
)
Package hyperref Info: Hyper figures OFF on input line 4062.
Package hyperref Info: Link nesting OFF on input line 4067.
Package hyperref Info: Hyper index ON on input line 4070.
Package hyperref Info: Plain pages OFF on input line 4077.
Package hyperref Info: Backreferencing OFF on input line 4082.
Package hyperref Info: Implicit mode ON; LaTeX internals redefined.
Package hyperref Info: Bookmarks ON on input line 4300.
\c@Hy@tempcnt=\count93
(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty
\Urlmuskip=\muskip10
Package: url 2006/04/12 ver 3.3 Verb mode for urls, etc.
)
LaTeX Info: Redefining \url on input line 4653.
\Fld@menulength=\count94
\Field@Width=\dimen108
\Fld@charsize=\dimen109
Package hyperref Info: Hyper figures OFF on input line 5773.
Package hyperref Info: Link nesting OFF on input line 5778.
Package hyperref Info: Hyper index ON on input line 5781.
Package hyperref Info: backreferencing OFF on input line 5788.
Package hyperref Info: Link coloring OFF on input line 5793.
Package hyperref Info: Link coloring with OCG OFF on input line 5798.
Package hyperref Info: PDF/A mode OFF on input line 5803.
LaTeX Info: Redefining \ref on input line 5843.
LaTeX Info: Redefining \pageref on input line 5847.
\Hy@abspage=\count95
\c@Item=\count96
\c@Hfootnote=\count97
)
Package hyperref Message: Driver (autodetected): hpdftex.
(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hpdftex.def
File: hpdftex.def 2012/05/13 v6.82q Hyperref driver for pdfTeX
\Fld@listcount=\count98
\c@bookmark@seq@number=\count99
(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty
Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO)
Package uniquecounter Info: New unique counter `rerunfilecheck' on input line 2
82.
)
\Hy@SectionHShift=\skip48
)
(/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty
Package: inputenc 2008/03/30 v1.1d Input encoding file
\inpenc@prehook=\toks19
\inpenc@posthook=\toks20
(/usr/share/texlive/texmf-dist/tex/latex/base/utf8.def
File: utf8.def 2008/04/05 v1.1m UTF-8 support for inputenc
Now handling font encoding OML ...
... no UTF-8 mapping file for font encoding OML
Now handling font encoding T1 ...
... processing UTF-8 mapping file for font encoding T1
(/usr/share/texlive/texmf-dist/tex/latex/base/t1enc.dfu
File: t1enc.dfu 2008/04/05 v1.1m UTF-8 support for inputenc
defining Unicode char U+00A1 (decimal 161)
defining Unicode char U+00A3 (decimal 163)
defining Unicode char U+00AB (decimal 171)
defining Unicode char U+00BB (decimal 187)
defining Unicode char U+00BF (decimal 191)
defining Unicode char U+00C0 (decimal 192)
defining Unicode char U+00C1 (decimal 193)
defining Unicode char U+00C2 (decimal 194)
defining Unicode char U+00C3 (decimal 195)
defining Unicode char U+00C4 (decimal 196)
defining Unicode char U+00C5 (decimal 197)
defining Unicode char U+00C6 (decimal 198)
defining Unicode char U+00C7 (decimal 199)
defining Unicode char U+00C8 (decimal 200)
defining Unicode char U+00C9 (decimal 201)
defining Unicode char U+00CA (decimal 202)
defining Unicode char U+00CB (decimal 203)
defining Unicode char U+00CC (decimal 204)
defining Unicode char U+00CD (decimal 205)
defining Unicode char U+00CE (decimal 206)
defining Unicode char U+00CF (decimal 207)
defining Unicode char U+00D0 (decimal 208)
defining Unicode char U+00D1 (decimal 209)
defining Unicode char U+00D2 (decimal 210)
defining Unicode char U+00D3 (decimal 211)
defining Unicode char U+00D4 (decimal 212)
defining Unicode char U+00D5 (decimal 213)
defining Unicode char U+00D6 (decimal 214)
defining Unicode char U+00D8 (decimal 216)
defining Unicode char U+00D9 (decimal 217)
defining Unicode char U+00DA (decimal 218)
defining Unicode char U+00DB (decimal 219)
defining Unicode char U+00DC (decimal 220)
defining Unicode char U+00DD (decimal 221)
defining Unicode char U+00DE (decimal 222)
defining Unicode char U+00DF (decimal 223)
defining Unicode char U+00E0 (decimal 224)
defining Unicode char U+00E1 (decimal 225)
defining Unicode char U+00E2 (decimal 226)
defining Unicode char U+00E3 (decimal 227)
defining Unicode char U+00E4 (decimal 228)
defining Unicode char U+00E5 (decimal 229)
defining Unicode char U+00E6 (decimal 230)
defining Unicode char U+00E7 (decimal 231)
defining Unicode char U+00E8 (decimal 232)
defining Unicode char U+00E9 (decimal 233)
defining Unicode char U+00EA (decimal 234)
defining Unicode char U+00EB (decimal 235)
defining Unicode char U+00EC (decimal 236)
defining Unicode char U+00ED (decimal 237)
defining Unicode char U+00EE (decimal 238)
defining Unicode char U+00EF (decimal 239)
defining Unicode char U+00F0 (decimal 240)
defining Unicode char U+00F1 (decimal 241)
defining Unicode char U+00F2 (decimal 242)
defining Unicode char U+00F3 (decimal 243)
defining Unicode char U+00F4 (decimal 244)
defining Unicode char U+00F5 (decimal 245)
defining Unicode char U+00F6 (decimal 246)
defining Unicode char U+00F8 (decimal 248)
defining Unicode char U+00F9 (decimal 249)
defining Unicode char U+00FA (decimal 250)
defining Unicode char U+00FB (decimal 251)
defining Unicode char U+00FC (decimal 252)
defining Unicode char U+00FD (decimal 253)
defining Unicode char U+00FE (decimal 254)
defining Unicode char U+00FF (decimal 255)
defining Unicode char U+0102 (decimal 258)
defining Unicode char U+0103 (decimal 259)
defining Unicode char U+0104 (decimal 260)
defining Unicode char U+0105 (decimal 261)
defining Unicode char U+0106 (decimal 262)
defining Unicode char U+0107 (decimal 263)
defining Unicode char U+010C (decimal 268)
defining Unicode char U+010D (decimal 269)
defining Unicode char U+010E (decimal 270)
defining Unicode char U+010F (decimal 271)
defining Unicode char U+0110 (decimal 272)
defining Unicode char U+0111 (decimal 273)
defining Unicode char U+0118 (decimal 280)
defining Unicode char U+0119 (decimal 281)
defining Unicode char U+011A (decimal 282)
defining Unicode char U+011B (decimal 283)
defining Unicode char U+011E (decimal 286)
defining Unicode char U+011F (decimal 287)
defining Unicode char U+0130 (decimal 304)
defining Unicode char U+0131 (decimal 305)
defining Unicode char U+0132 (decimal 306)
defining Unicode char U+0133 (decimal 307)
defining Unicode char U+0139 (decimal 313)
defining Unicode char U+013A (decimal 314)
defining Unicode char U+013D (decimal 317)
defining Unicode char U+013E (decimal 318)
defining Unicode char U+0141 (decimal 321)
defining Unicode char U+0142 (decimal 322)
defining Unicode char U+0143 (decimal 323)
defining Unicode char U+0144 (decimal 324)
defining Unicode char U+0147 (decimal 327)
defining Unicode char U+0148 (decimal 328)
defining Unicode char U+014A (decimal 330)
defining Unicode char U+014B (decimal 331)
defining Unicode char U+0150 (decimal 336)
defining Unicode char U+0151 (decimal 337)
defining Unicode char U+0152 (decimal 338)
defining Unicode char U+0153 (decimal 339)
defining Unicode char U+0154 (decimal 340)
defining Unicode char U+0155 (decimal 341)
defining Unicode char U+0158 (decimal 344)
defining Unicode char U+0159 (decimal 345)
defining Unicode char U+015A (decimal 346)
defining Unicode char U+015B (decimal 347)
defining Unicode char U+015E (decimal 350)
defining Unicode char U+015F (decimal 351)
defining Unicode char U+0160 (decimal 352)
defining Unicode char U+0161 (decimal 353)
defining Unicode char U+0162 (decimal 354)
defining Unicode char U+0163 (decimal 355)
defining Unicode char U+0164 (decimal 356)
defining Unicode char U+0165 (decimal 357)
defining Unicode char U+016E (decimal 366)
defining Unicode char U+016F (decimal 367)
defining Unicode char U+0170 (decimal 368)
defining Unicode char U+0171 (decimal 369)
defining Unicode char U+0178 (decimal 376)
defining Unicode char U+0179 (decimal 377)
defining Unicode char U+017A (decimal 378)
defining Unicode char U+017B (decimal 379)
defining Unicode char U+017C (decimal 380)
defining Unicode char U+017D (decimal 381)
defining Unicode char U+017E (decimal 382)
defining Unicode char U+200C (decimal 8204)
defining Unicode char U+2013 (decimal 8211)
defining Unicode char U+2014 (decimal 8212)
defining Unicode char U+2018 (decimal 8216)
defining Unicode char U+2019 (decimal 8217)
defining Unicode char U+201A (decimal 8218)
defining Unicode char U+201C (decimal 8220)
defining Unicode char U+201D (decimal 8221)
defining Unicode char U+201E (decimal 8222)
defining Unicode char U+2030 (decimal 8240)
defining Unicode char U+2031 (decimal 8241)
defining Unicode char U+2039 (decimal 8249)
defining Unicode char U+203A (decimal 8250)
defining Unicode char U+2423 (decimal 9251)
)
Now handling font encoding OT1 ...
... processing UTF-8 mapping file for font encoding OT1
(/usr/share/texlive/texmf-dist/tex/latex/base/ot1enc.dfu
File: ot1enc.dfu 2008/04/05 v1.1m UTF-8 support for inputenc
defining Unicode char U+00A1 (decimal 161)
defining Unicode char U+00A3 (decimal 163)
defining Unicode char U+00B8 (decimal 184)
defining Unicode char U+00BF (decimal 191)
defining Unicode char U+00C5 (decimal 197)
defining Unicode char U+00C6 (decimal 198)
defining Unicode char U+00D8 (decimal 216)
defining Unicode char U+00DF (decimal 223)
defining Unicode char U+00E6 (decimal 230)
defining Unicode char U+00EC (decimal 236)
defining Unicode char U+00ED (decimal 237)
defining Unicode char U+00EE (decimal 238)
defining Unicode char U+00EF (decimal 239)
defining Unicode char U+00F8 (decimal 248)
defining Unicode char U+0131 (decimal 305)
defining Unicode char U+0141 (decimal 321)
defining Unicode char U+0142 (decimal 322)
defining Unicode char U+0152 (decimal 338)
defining Unicode char U+0153 (decimal 339)
defining Unicode char U+2013 (decimal 8211)
defining Unicode char U+2014 (decimal 8212)
defining Unicode char U+2018 (decimal 8216)
defining Unicode char U+2019 (decimal 8217)
defining Unicode char U+201C (decimal 8220)
defining Unicode char U+201D (decimal 8221)
)
Now handling font encoding OMS ...
... processing UTF-8 mapping file for font encoding OMS
(/usr/share/texlive/texmf-dist/tex/latex/base/omsenc.dfu
File: omsenc.dfu 2008/04/05 v1.1m UTF-8 support for inputenc
defining Unicode char U+00A7 (decimal 167)
defining Unicode char U+00B6 (decimal 182)
defining Unicode char U+00B7 (decimal 183)
defining Unicode char U+2020 (decimal 8224)
defining Unicode char U+2021 (decimal 8225)
defining Unicode char U+2022 (decimal 8226)
)
Now handling font encoding OMX ...
... no UTF-8 mapping file for font encoding OMX
Now handling font encoding U ...
... no UTF-8 mapping file for font encoding U
Now handling font encoding PD1 ...
... no UTF-8 mapping file for font encoding PD1
defining Unicode char U+00A9 (decimal 169)
defining Unicode char U+00AA (decimal 170)
defining Unicode char U+00AE (decimal 174)
defining Unicode char U+00BA (decimal 186)
defining Unicode char U+02C6 (decimal 710)
defining Unicode char U+02DC (decimal 732)
defining Unicode char U+200C (decimal 8204)
defining Unicode char U+2026 (decimal 8230)
defining Unicode char U+2122 (decimal 8482)
defining Unicode char U+2423 (decimal 9251)
))
(/usr/share/texlive/texmf-dist/tex/latex/base/alltt.sty
Package: alltt 1997/06/16 v2.0g defines alltt environment
)
(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty
Package: amsmath 2000/07/18 v2.13 AMS math features
\@mathmargin=\skip49
For additional information on amsmath, use the `?' option.
(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty
Package: amstext 2000/06/29 v2.01
(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty
File: amsgen.sty 1999/11/30 v2.0
\@emptytoks=\toks21
\ex@=\dimen110
))
(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty
Package: amsbsy 1999/11/29 v1.2d
\pmbraise@=\dimen111
)
(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty
Package: amsopn 1999/12/14 v2.01 operator names
)
\inf@bad=\count100
LaTeX Info: Redefining \frac on input line 211.
\uproot@=\count101
\leftroot@=\count102
LaTeX Info: Redefining \overline on input line 307.
\classnum@=\count103
\DOTSCASE@=\count104
LaTeX Info: Redefining \ldots on input line 379.
LaTeX Info: Redefining \dots on input line 382.
LaTeX Info: Redefining \cdots on input line 467.
\Mathstrutbox@=\box26
\strutbox@=\box27
\big@size=\dimen112
LaTeX Font Info: Redeclaring font encoding OML on input line 567.
LaTeX Font Info: Redeclaring font encoding OMS on input line 568.
\macc@depth=\count105
\c@MaxMatrixCols=\count106
\dotsspace@=\muskip11
\c@parentequation=\count107
\dspbrk@lvl=\count108
\tag@help=\toks22
\row@=\count109
\column@=\count110
\maxfields@=\count111
\andhelp@=\toks23
\eqnshift@=\dimen113
\alignsep@=\dimen114
\tagshift@=\dimen115
\tagwidth@=\dimen116
\totwidth@=\dimen117
\lineht@=\dimen118
\@envbody=\toks24
\multlinegap=\skip50
\multlinetaggap=\skip51
\mathdisplay@stack=\toks25
LaTeX Info: Redefining \[ on input line 2666.
LaTeX Info: Redefining \] on input line 2667.
)
(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty
Package: amssymb 2009/06/22 v3.00
(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty
Package: amsfonts 2009/06/22 v3.00 Basic AMSFonts support
\symAMSa=\mathgroup4
\symAMSb=\mathgroup5
LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold'
(Font) U/euf/m/n --> U/euf/b/n on input line 96.
))
(/usr/share/texlive/texmf-dist/tex/latex/txfonts/txfonts.sty
Package: txfonts 2008/01/22 v3.2.1
LaTeX Font Info: Redeclaring symbol font `operators' on input line 21.
LaTeX Font Info: Overwriting symbol font `operators' in version `normal'
(Font) OT1/cmr/m/n --> OT1/txr/m/n on input line 21.
LaTeX Font Info: Overwriting symbol font `operators' in version `bold'
(Font) OT1/cmr/bx/n --> OT1/txr/m/n on input line 21.
LaTeX Font Info: Overwriting symbol font `operators' in version `bold'
(Font) OT1/txr/m/n --> OT1/txr/bx/n on input line 22.
\symitalic=\mathgroup6
LaTeX Font Info: Overwriting symbol font `italic' in version `bold'
(Font) OT1/txr/m/it --> OT1/txr/bx/it on input line 26.
LaTeX Font Info: Redeclaring math alphabet \mathbf on input line 29.
LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal'
(Font) OT1/cmr/bx/n --> OT1/txr/bx/n on input line 29.
LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `bold'
(Font) OT1/cmr/bx/n --> OT1/txr/bx/n on input line 29.
LaTeX Font Info: Redeclaring math alphabet \mathit on input line 30.
LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal'
(Font) OT1/cmr/m/it --> OT1/txr/m/it on input line 30.
LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold'
(Font) OT1/cmr/bx/it --> OT1/txr/m/it on input line 30.
LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold'
(Font) OT1/txr/m/it --> OT1/txr/bx/it on input line 31.
LaTeX Font Info: Redeclaring math alphabet \mathsf on input line 40.
LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal'
(Font) OT1/cmss/m/n --> OT1/txss/m/n on input line 40.
LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold'
(Font) OT1/cmss/bx/n --> OT1/txss/m/n on input line 40.
LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold'
(Font) OT1/txss/m/n --> OT1/txss/b/n on input line 41.
LaTeX Font Info: Redeclaring math alphabet \mathtt on input line 50.
LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal'
(Font) OT1/cmtt/m/n --> OT1/txtt/m/n on input line 50.
LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold'
(Font) OT1/cmtt/m/n --> OT1/txtt/m/n on input line 50.
LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold'
(Font) OT1/txtt/m/n --> OT1/txtt/b/n on input line 51.
LaTeX Font Info: Redeclaring symbol font `letters' on input line 58.
LaTeX Font Info: Overwriting symbol font `letters' in version `normal'
(Font) OML/cmm/m/it --> OML/txmi/m/it on input line 58.
LaTeX Font Info: Overwriting symbol font `letters' in version `bold'
(Font) OML/cmm/b/it --> OML/txmi/m/it on input line 58.
LaTeX Font Info: Overwriting symbol font `letters' in version `bold'
(Font) OML/txmi/m/it --> OML/txmi/bx/it on input line 59.
\symlettersA=\mathgroup7
LaTeX Font Info: Overwriting symbol font `lettersA' in version `bold'
(Font) U/txmia/m/it --> U/txmia/bx/it on input line 67.
LaTeX Font Info: Redeclaring math alphabet \mathfrak on input line 70.
LaTeX Font Info: Redeclaring symbol font `symbols' on input line 77.
LaTeX Font Info: Overwriting symbol font `symbols' in version `normal'
(Font) OMS/cmsy/m/n --> OMS/txsy/m/n on input line 77.
LaTeX Font Info: Overwriting symbol font `symbols' in version `bold'
(Font) OMS/cmsy/b/n --> OMS/txsy/m/n on input line 77.
LaTeX Font Info: Overwriting symbol font `symbols' in version `bold'
(Font) OMS/txsy/m/n --> OMS/txsy/bx/n on input line 78.
LaTeX Font Info: Redeclaring symbol font `AMSa' on input line 93.
LaTeX Font Info: Overwriting symbol font `AMSa' in version `normal'
(Font) U/msa/m/n --> U/txsya/m/n on input line 93.
LaTeX Font Info: Overwriting symbol font `AMSa' in version `bold'
(Font) U/msa/m/n --> U/txsya/m/n on input line 93.
LaTeX Font Info: Overwriting symbol font `AMSa' in version `bold'
(Font) U/txsya/m/n --> U/txsya/bx/n on input line 94.
LaTeX Font Info: Redeclaring symbol font `AMSb' on input line 102.
LaTeX Font Info: Overwriting symbol font `AMSb' in version `normal'
(Font) U/msb/m/n --> U/txsyb/m/n on input line 102.
LaTeX Font Info: Overwriting symbol font `AMSb' in version `bold'
(Font) U/msb/m/n --> U/txsyb/m/n on input line 102.
LaTeX Font Info: Overwriting symbol font `AMSb' in version `bold'
(Font) U/txsyb/m/n --> U/txsyb/bx/n on input line 103.
\symsymbolsC=\mathgroup8
LaTeX Font Info: Overwriting symbol font `symbolsC' in version `bold'
(Font) U/txsyc/m/n --> U/txsyc/bx/n on input line 113.
LaTeX Font Info: Redeclaring symbol font `largesymbols' on input line 120.
LaTeX Font Info: Overwriting symbol font `largesymbols' in version `normal'
(Font) OMX/cmex/m/n --> OMX/txex/m/n on input line 120.
LaTeX Font Info: Overwriting symbol font `largesymbols' in version `bold'
(Font) OMX/cmex/m/n --> OMX/txex/m/n on input line 120.
LaTeX Font Info: Overwriting symbol font `largesymbols' in version `bold'
(Font) OMX/txex/m/n --> OMX/txex/bx/n on input line 121.
\symlargesymbolsA=\mathgroup9
LaTeX Font Info: Overwriting symbol font `largesymbolsA' in version `bold'
(Font) U/txexa/m/n --> U/txexa/bx/n on input line 129.
LaTeX Info: Redefining \not on input line 1043.
)
(/usr/share/texlive/texmf-dist/tex/latex/anysize/anysize.sty
Package: anysize 1994/08/13 setting margin sizes
document style option `anysize' loaded
Michael Salzenberg, Thomas Esser, Dirk Hillbrecht
Version 1.0, Aug 13, 1994
\@Leftmargin=\dimen119
\@Rightmargin=\dimen120
\@Topmargin=\dimen121
\@Bottommargin=\dimen122
) (/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty
\fancy@headwidth=\skip52
\f@ncyO@elh=\skip53
\f@ncyO@erh=\skip54
\f@ncyO@olh=\skip55
\f@ncyO@orh=\skip56
\f@ncyO@elf=\skip57
\f@ncyO@erf=\skip58
\f@ncyO@olf=\skip59
\f@ncyO@orf=\skip60
) (./main.aux)
\openout1 = `main.aux'.
LaTeX Font Info: Checking defaults for OML/txmi/m/it on input line 58.
LaTeX Font Info: Try loading font information for OML+txmi on input line 58.
(/usr/share/texlive/texmf-dist/tex/latex/txfonts/omltxmi.fd
File: omltxmi.fd 2000/12/15 v3.1
)
LaTeX Font Info: ... okay on input line 58.
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 58.
LaTeX Font Info: ... okay on input line 58.
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 58.
LaTeX Font Info: ... okay on input line 58.
LaTeX Font Info: Checking defaults for OMS/txsy/m/n on input line 58.
LaTeX Font Info: Try loading font information for OMS+txsy on input line 58.
(/usr/share/texlive/texmf-dist/tex/latex/txfonts/omstxsy.fd
File: omstxsy.fd 2000/12/15 v3.1
)
LaTeX Font Info: ... okay on input line 58.
LaTeX Font Info: Checking defaults for OMX/txex/m/n on input line 58.
LaTeX Font Info: Try loading font information for OMX+txex on input line 58.
(/usr/share/texlive/texmf-dist/tex/latex/txfonts/omxtxex.fd
File: omxtxex.fd 2000/12/15 v3.1
)
LaTeX Font Info: ... okay on input line 58.
LaTeX Font Info: Checking defaults for U/txexa/m/n on input line 58.
LaTeX Font Info: Try loading font information for U+txexa on input line 58.
(/usr/share/texlive/texmf-dist/tex/latex/txfonts/utxexa.fd
File: utxexa.fd 2000/12/15 v3.1
)
LaTeX Font Info: ... okay on input line 58.
LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 58.
LaTeX Font Info: ... okay on input line 58.
LaTeX Font Info: Try loading font information for OT1+txr on input line 58.
(/usr/share/texlive/texmf-dist/tex/latex/txfonts/ot1txr.fd
File: ot1txr.fd 2000/12/15 v3.1
)
(/usr/share/texlive/texmf-dist/tex/context/base/supp-pdf.mkii
[Loading MPS to PDF converter (version 2006.09.02).]
\scratchcounter=\count112
\scratchdimen=\dimen123
\scratchbox=\box28
\nofMPsegments=\count113
\nofMParguments=\count114
\everyMPshowfont=\toks26
\MPscratchCnt=\count115
\MPscratchDim=\dimen124
\MPnumerator=\count116
\makeMPintoPDFobject=\count117
\everyMPtoPDFconversion=\toks27
) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/epstopdf-base.sty
Package: epstopdf-base 2010/02/09 v2.5 Base part for package epstopdf
(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/grfext.sty
Package: grfext 2010/08/19 v1.1 Manage graphics extensions (HO)
)
Package grfext Info: Graphics extension search list:
(grfext) [.png,.pdf,.jpg,.mps,.jpeg,.jbig2,.jb2,.PNG,.PDF,.JPG,.JPE
G,.JBIG2,.JB2,.eps]
(grfext) \AppendGraphicsExtensions on input line 452.
(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg
File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv
e
))
\AtBeginShipoutBox=\box29
Package hyperref Info: Link coloring OFF on input line 58.
(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty
Package: nameref 2010/04/30 v2.40 Cross-referencing by name of section
(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty
Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO)
)
\c@section@level=\count118
)
LaTeX Info: Redefining \ref on input line 58.
LaTeX Info: Redefining \pageref on input line 58.
LaTeX Info: Redefining \nameref on input line 58.
(./main.out) (./main.out)
\@outlinefile=\write3
\openout3 = `main.out'.
LaTeX Font Info: Try loading font information for U+txsya on input line 64.
(/usr/share/texlive/texmf-dist/tex/latex/txfonts/utxsya.fd
File: utxsya.fd 2000/12/15 v3.1
)
LaTeX Font Info: Try loading font information for U+txsyb on input line 64.
(/usr/share/texlive/texmf-dist/tex/latex/txfonts/utxsyb.fd
File: utxsyb.fd 2000/12/15 v3.1
)
LaTeX Font Info: Try loading font information for U+txmia on input line 64.
(/usr/share/texlive/texmf-dist/tex/latex/txfonts/utxmia.fd
File: utxmia.fd 2000/12/15 v3.1
)
LaTeX Font Info: Try loading font information for U+txsyc on input line 64.
(/usr/share/texlive/texmf-dist/tex/latex/txfonts/utxsyc.fd
File: utxsyc.fd 2000/12/15 v3.1
)
<./images/CC_88x31.png, id=92, 88.33pt x 31.11626pt>
File: ./images/CC_88x31.png Graphic file (type png)
<use ./images/CC_88x31.png>
Package pdftex.def Info: ./images/CC_88x31.png used on input line 64.
(pdftex.def) Requested size: 105.27359pt x 37.08528pt.
[1
{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map} <./images/CC_88x31.png>] [2
] (./main.toc)
\tf@toc=\write4
\openout4 = `main.toc'.
Package Fancyhdr Warning: \headheight is too small (12.0pt):
Make it at least 14.49998pt.
We now make it that large for the rest of the document.
This may cause the page layout to be inconsistent, however.
[3] (./abstract.tex [4
]
Chapter 1.
[5] [6
]
Chapter 2.
) (./laplace2D.tex [7] [8
]
Chapter 3.
[9] [10] <./images/Omega.png, id=189, 806.01125pt x 479.7925pt>
File: ./images/Omega.png Graphic file (type png)
<use ./images/Omega.png>
Package pdftex.def Info: ./images/Omega.png used on input line 179.
(pdftex.def) Requested size: 210.54718pt x 125.32878pt.
) (./laplace3D.tex [11 <./images/Omega.png>] [12
]
Chapter 4.
[13] <./images/Omega2.png, id=218, 1132.23pt x 449.68pt>
File: ./images/Omega2.png Graphic file (type png)
<use ./images/Omega2.png>
Package pdftex.def Info: ./images/Omega2.png used on input line 117.
(pdftex.def) Requested size: 315.82881pt x 125.43608pt.
[14 <./images/Omega2.png>] [15] [16] [17]
<./images/Integral.png, id=281, 699.61375pt x 699.61375pt>
File: ./images/Integral.png Graphic file (type png)
<use ./images/Integral.png>
Package pdftex.def Info: ./images/Integral.png used on input line 561.
(pdftex.def) Requested size: 315.82881pt x 315.82675pt.
<./images/test_wave.png, id=283, 586.8324pt x 442.2924pt>
File: ./images/test_wave.png Graphic file (type png)
<use ./images/test_wave.png>
Package pdftex.def Info: ./images/test_wave.png used on input line 585.
(pdftex.def) Requested size: 315.82881pt x 238.04472pt.
[18] [19 <./images/Integral.png> <./images/test_wave.png>] <./images/test_dire
ct.png, id=301, 586.8324pt x 442.2924pt>
File: ./images/test_direct.png Graphic file (type png)
<use ./images/test_direct.png>
Package pdftex.def Info: ./images/test_direct.png used on input line 616.
(pdftex.def) Requested size: 315.82881pt x 238.04472pt.
<./images/test_bem.png, id=304, 586.8324pt x 442.2924pt>
File: ./images/test_bem.png Graphic file (type png)
<use ./images/test_bem.png>
Package pdftex.def Info: ./images/test_bem.png used on input line 638.
(pdftex.def) Requested size: 315.82881pt x 238.04472pt.
) (./main.bbl [20 <./images/test_direct.png>]
[21 <./images/test_bem.png>] [22
])
Package atveryend Info: Empty hook `BeforeClearDocument' on input line 90.
[23]
Package atveryend Info: Empty hook `AfterLastShipout' on input line 90.
(./main.aux)
Package atveryend Info: Executing hook `AtVeryEndDocument' on input line 90.
Package atveryend Info: Executing hook `AtEndAfterFileList' on input line 90.
Package rerunfilecheck Info: File `main.out' has not changed.
(rerunfilecheck) Checksum: 47992CAAC05675F8055DF1DA37B7F7A8;1434.
Package atveryend Info: Empty hook `AtVeryVeryEnd' on input line 90.
)
Here is how much of TeX's memory you used:
7457 strings out of 495059
103785 string characters out of 3182029
206801 words of memory out of 3000000
10379 multiletter control sequences out of 15000+200000
53484 words of font info for 126 fonts, out of 3000000 for 9000
14 hyphenation exceptions out of 8191
34i,17n,43p,237b,351s stack positions out of 5000i,500n,10000p,200000b,50000s
{/usr/share/texlive/texmf-dist/fonts/enc/dvips/base/8r.enc}</usr/share/texliv
e/texmf-dist/fonts/type1/public/txfonts/rtxmi.pfb></usr/share/texlive/texmf-dis
t/fonts/type1/public/txfonts/rtxr.pfb></usr/share/texlive/texmf-dist/fonts/type
1/public/txfonts/txex.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/txf
onts/txsy.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/txfonts/txsyc.p
fb></usr/share/texlive/texmf-dist/fonts/type1/urw/times/utmb8a.pfb></usr/share/
texlive/texmf-dist/fonts/type1/urw/times/utmr8a.pfb></usr/share/texlive/texmf-d
ist/fonts/type1/urw/times/utmri8a.pfb>
Output written on main.pdf (23 pages, 322361 bytes).
PDF statistics:
376 PDF objects out of 1000 (max. 8388607)
325 compressed objects within 4 object streams
96 named destinations out of 1000 (max. 500000)
212 words of extra memory for PDF output out of 10000 (max. 10000000)

View File

@ -0,0 +1,22 @@
\BOOKMARK [0][-]{chapter.1}{Introduction}{}% 1
\BOOKMARK [1][-]{section.1.1}{Objective}{chapter.1}% 2
\BOOKMARK [0][-]{chapter.2}{Governing equations}{}% 3
\BOOKMARK [0][-]{chapter.3}{Waves propagations in 2D plane}{}% 4
\BOOKMARK [1][-]{section.3.1}{General}{chapter.3}% 5
\BOOKMARK [1][-]{section.3.2}{Incident waves}{chapter.3}% 6
\BOOKMARK [1][-]{section.3.3}{BEM applied to Laplace 2D problem}{chapter.3}% 7
\BOOKMARK [1][-]{section.3.4}{Conclusions to Laplace 2D problem}{chapter.3}% 8
\BOOKMARK [0][-]{chapter.4}{Waves propagations in 3D}{}% 9
\BOOKMARK [1][-]{section.4.1}{General}{chapter.4}% 10
\BOOKMARK [1][-]{section.4.2}{Incident waves}{chapter.4}% 11
\BOOKMARK [1][-]{section.4.3}{BEM applied to Laplace 3D problem}{chapter.4}% 12
\BOOKMARK [2][-]{subsection.4.3.1}{Computational domain}{section.4.3}% 13
\BOOKMARK [2][-]{subsection.4.3.2}{Boundary conditions \(BC\)}{section.4.3}% 14
\BOOKMARK [2][-]{subsection.4.3.3}{Time integration scheme}{section.4.3}% 15
\BOOKMARK [2][-]{subsection.4.3.4}{Discrete Laplace solution using the BEM}{section.4.3}% 16
\BOOKMARK [2][-]{subsection.4.3.5}{Integrals computation}{section.4.3}% 17
\BOOKMARK [1][-]{section.4.4}{BEM test}{chapter.4}% 18
\BOOKMARK [2][-]{subsection.4.4.1}{General}{section.4.4}% 19
\BOOKMARK [2][-]{subsection.4.4.2}{Direct method}{section.4.4}% 20
\BOOKMARK [2][-]{subsection.4.4.3}{BEM}{section.4.4}% 21
\BOOKMARK [0][-]{chapter*.2}{Bibliography}{}% 22

Binary file not shown.

View File

@ -0,0 +1,90 @@
\documentclass[a4paper,12pt]{book}
\usepackage[numbers]{natbib}
\bibliographystyle{plainnat}
\usepackage{graphicx}
\usepackage{verbatim}
\usepackage{color, colortbl}
\usepackage{hyperref}
\usepackage[utf8]{inputenc}
\setcounter{tocdepth}{2}
\usepackage{alltt}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsfonts}
\graphicspath{{./images/}}
\usepackage{txfonts} %%does not work on Windows
% \usepackage{dsfont}
%
\newcommand{\NAME}{FreeCAD-Ship }
\newcommand{\rc}{\\[0.2 in]}
\newcommand{\rcc}{\\[0.3 in]}
\newcommand{\rccc}{\\[0.4 in]}
% \newcommand{\bs}[1]{\boldsymbol{#1}}
\newcommand{\bs}[1]{\pmb{#1}}
\newcommand{\SPHint}{\int_{\bs{y} \in \Omega}}
\newcommand{\SPHboundint}{\int_{\bs{y} \in \partial \Omega}}
\newcommand{\gradient}{\nabla}
\newcommand{\divergence}{\mbox{div}}
\newcommand{\rotational}{\nabla \times}
\newcommand{\laplacian}{\bigtriangleup}
\newcommand{\dsty}{\displaystyle}
\newcommand{\sph}[1]{\langle {#1} \rangle}
%
\author{JL Cercos-Pita $<$jlcercos@gmail.com$>$}
\title{FreeCAD-Ship.\rcc
\textbf{Sea waves transport using Boundary Elements Method}}
\date{\today\\[5.0 in]
\begin{figure}[h!]
\centering
\includegraphics[width=0.2\textwidth]{CC_88x31}
\end{figure}
}
%
\setlength{\parindent}{0em}
%
\usepackage{anysize}
\marginsize{1.5cm}{1cm}{1cm}{1cm}
%
\usepackage{fancyhdr}
\pagestyle{fancyplain}
% Pages header and foot
\lhead{}
\rhead{\NAME}
\lfoot{JL Cercos-Pita}
\cfoot{jlcercos@gmail.com}
\rfoot{\thepage}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
% -------------------------------
% Title and summary
% -------------------------------
\maketitle
\thispagestyle{empty}
%
\newpage
\tableofcontents
\newpage
\newpage
% -------------------------------
% Introduction
% -------------------------------
\input{abstract}
% -------------------------------
% Laplacian 2D
% -------------------------------
\input{laplace2D}
% -------------------------------
% Laplacian 2D
% -------------------------------
\input{laplace3D}
% -------------------------------
% Bibliography
% -------------------------------
\bibliography{bib}
\addcontentsline{toc}{chapter}{Bibliography}
\end{document}

View File

@ -0,0 +1,22 @@
\contentsline {chapter}{\numberline {1}Introduction}{5}{chapter.1}
\contentsline {section}{\numberline {1.1}Objective}{5}{section.1.1}
\contentsline {chapter}{\numberline {2}Governing equations}{7}{chapter.2}
\contentsline {chapter}{\numberline {3}Waves propagations in 2D plane}{9}{chapter.3}
\contentsline {section}{\numberline {3.1}General}{9}{section.3.1}
\contentsline {section}{\numberline {3.2}Incident waves}{9}{section.3.2}
\contentsline {section}{\numberline {3.3}BEM applied to Laplace 2D problem}{10}{section.3.3}
\contentsline {section}{\numberline {3.4}Conclusions to Laplace 2D problem}{11}{section.3.4}
\contentsline {chapter}{\numberline {4}Waves propagations in 3D}{13}{chapter.4}
\contentsline {section}{\numberline {4.1}General}{13}{section.4.1}
\contentsline {section}{\numberline {4.2}Incident waves}{13}{section.4.2}
\contentsline {section}{\numberline {4.3}BEM applied to Laplace 3D problem}{13}{section.4.3}
\contentsline {subsection}{\numberline {4.3.1}Computational domain}{13}{subsection.4.3.1}
\contentsline {subsection}{\numberline {4.3.2}Boundary conditions (BC)}{14}{subsection.4.3.2}
\contentsline {subsection}{\numberline {4.3.3}Time integration scheme}{15}{subsection.4.3.3}
\contentsline {subsection}{\numberline {4.3.4}Discrete Laplace solution using the BEM}{16}{subsection.4.3.4}
\contentsline {subsection}{\numberline {4.3.5}Integrals computation}{17}{subsection.4.3.5}
\contentsline {section}{\numberline {4.4}BEM test}{18}{section.4.4}
\contentsline {subsection}{\numberline {4.4.1}General}{18}{subsection.4.4.1}
\contentsline {subsection}{\numberline {4.4.2}Direct method}{19}{subsection.4.4.2}
\contentsline {subsection}{\numberline {4.4.3}BEM}{20}{subsection.4.4.3}
\contentsline {chapter}{Bibliography}{23}{chapter*.2}

View File

@ -0,0 +1,127 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
from numpy import *
import waves
def G_val(x,X):
""" Computed the Green's function value.
@param x Point to evaluate (numpy.array(3))
@param X Reference point (numpy.array(3))
@return Green's function value.
"""
return 1.0 / (4.0*pi * linalg.norm(x-X))
def H_val(x,X):
""" Computed the Green's function gradient.
@param x Point to evaluate (numpy.array(3))
@param X Reference point (numpy.array(3))
@return Green's function gradient.
"""
return (x-X) / (4.0*pi * dot(x-X, x-X)**1.5 )
def GH(p,I,J,P,n,L,B,x,y,z,dx,dy,t, a,k,w,d):
""" Computes the Green's function integral
numerically, with an increase resolution of n.
@param p Point to evaluate
@param I Point to evaluate x index
@param J Point to evaluate y index
@param P Reference point
@param n Number of divisors in each direction to
discretize each area element. Should be an even value
@param L Length of the computational domain
@param B width of the computational domain
@param x X coordinates of the area elements
@param y Y coordinates of the area elements
@param z Z coordinates of the area elements
@param dx distance between elements in the x direction
@param dy distance between elements in the y direction
@param t Simulation time (s)
@param a List of waves amplitudes
@param k List of waves k
@param w List of waves omega
@param d List of waves lags.
@return Green's function integral.
"""
# Ensure that n is an even value. If n is even
# we can grant that any point will be placed
# in p, that can be eventually the same than
# P, being G and H functions bad defined.
if n % 2:
n = n + 1
# Get the new distance between Green's points
DX = dx / n
DY = dy / n
# Get the coordinates of all the grid points
# around the evaluation one
nx = x.shape[0]
ny = y.shape[1]
X = zeros((3,3),dtype=float32)
Y = zeros((3,3),dtype=float32)
Z = zeros((3,3),dtype=float32)
for i in range(0,3):
for j in range(0,3):
X[i,j] = p[0] + (i-1)*dx
Y[i,j] = p[1] + (j-1)*dy
if((X[i,j] > -0.5*L) and (X[i,j] < 0.5*L) and (Y[i,j] > -0.5*B) and (Y[i,j] < 0.5*B)):
Z[i,j] = z[I-1+i,J-1+j]
else:
Z[i,j] = waves.z(X[i,j],Y[i,j],t, a,k,w,d)
# Perform spline surface coeffs
K = zeros((3*3),dtype=float32)
K[0] = Z[0,0] # k_{0}
K[1] = 4*Z[1,0] - Z[2,0] - 3*Z[0,0] # k_{u}
K[2] = 4*Z[0,1] - Z[0,2] - 3*Z[0,0] # k_{v}
K[3] = Z[2,2] - 4*Z[2,1] + 3*Z[2,0] + \
3*Z[0,2] - 12*Z[0,1] + 9*Z[0,0] + \
-4*Z[1,2] + 16*Z[1,1] - 12*Z[1,0] # k_{uv}
K[4] = 2*Z[2,0] + 2*Z[0,0] - 4*Z[1,0] # k_{uu}
K[5] = 2*Z[0,2] + 2*Z[0,0] - 4*Z[0,1] # k_{vv}
K[6] = -2*Z[2,2] + 8*Z[2,1] - 6*Z[2,0] + \
-2*Z[0,2] + 8*Z[0,1] - 6*Z[0,0] + \
4*Z[1,2] - 16*Z[1,1] + 12*Z[1,0] # k_{uuv}
K[7] = -2*Z[2,2] + 4*Z[2,1] - 2*Z[2,0] + \
-6*Z[0,2] + 12*Z[0,1] - 6*Z[0,0] + \
8*Z[1,2] - 16*Z[1,1] + 8*Z[1,0] # k_{uuv}
K[8] = 4*Z[2,2] - 8*Z[2,1] + 4*Z[2,0] + \
4*Z[0,2] - 8*Z[0,1] + 4*Z[0,0] + \
-8*Z[1,2] + 16*Z[1,1] - 8*Z[1,0] # k_{uuvv}
# Loop around the point p collecting the integral
G_tot = 0.0
H_tot = zeros((3),dtype=float32)
for i in range(0,n):
for j in range(0,n):
xx = x[I,J] - 0.5*dx + (i+0.5)*DX
yy = y[I,J] - 0.5*dy + (j+0.5)*DY
# Interpolate z
u = (xx - X[0,0]) / (X[2,0] - X[0,0])
v = (yy - Y[0,0]) / (Y[0,2] - Y[0,0])
zz = K[0] + K[1]*u + K[2]*v + K[3]*u*v + \
K[4]*u*u + K[5]*v*v + K[6]*u*u*v + \
K[7]*u*v*v + K[8]*u*u*v*v
p = array([xx,yy,zz])
G_tot = G_tot + G_val(p,P)*DX*DY
H_tot = H_tot + H_val(p,P)*DX*DY
return (G_tot,H_tot)

View File

@ -0,0 +1,285 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
import sys
from numpy import*
import scipy.linalg as la
from pylab import *
from green import *
import waves
# ---------------------------------------------------
# Input data
# ---------------------------------------------------
# Computational free surface (the part where we will
# compute the fluid dynamics) definition
L = 20.0
B = 10.0
nx = 31
ny = 15
# Waves to use, defined by the wave amplitude period,
# and lag. X direction waves will be assumed.
# l = g*T^2 / (2*pi)
a = [0.1]
t = [2.5]
d = [0.0]
# Green's function maximum value (Error). Used to compute
# The maximum distance to extend the free surface.
G_error = 1e-1
# Green's functions integrals resolution (even values)
nG = 8
# ---------------------------------------------------
# Simulation setup
# ---------------------------------------------------
# Discretization
drx = L / nx
dry = B / ny
dS = drx*dry
# First we may compute how many domains must be
# included in each directions to reach the Green's
# function requested error.
x = (L-drx)/2.0
Nx = 0
Gx = G_error*10.0
while(Gx > G_error):
x = x + L
Nx = Nx + 1
p = zeros((3), dtype=float32)
P = zeros((3), dtype=float32)
p[0] = x
Gx = G_val(p,P)
print('{0} times the free surface must be duplicated in the x direction\n\tG={1}'.format(Nx,Gx))
y = (B-dry)/2.0
Ny = 0
Gy = G_error*10.0
while(Gy > G_error):
y = y + B
Ny = Ny + 1
p = zeros((3), dtype=float32)
P = zeros((3), dtype=float32)
p[1] = y
Gy = G_val(p,P)
print('{0} times the free surface must be duplicated in the y direction\n\tG={1}'.format(Ny,Gy))
# Now we can compute some additional data of the waves
k = []
w = []
c = []
for i in range(0,len(a)):
w.append(2*pi/t[i])
k.append(w[i]**2 / 9.81)
c.append(w[i]/k[i])
# We can intializate the free surface
x = zeros((nx,ny),dtype=float32)
y = zeros((nx,ny),dtype=float32)
z = zeros((nx,ny),dtype=float32)
gradz = zeros((nx,ny),dtype=float32)
p = zeros((nx,ny),dtype=float32)
gradp = zeros((nx,ny),dtype=float32)
for i in range(0,nx):
for j in range(0,ny):
x[i,j] = -0.5*L + (i+0.5)*drx
y[i,j] = -0.5*B + (j+0.5)*dry
z[i,j] = waves.z(x[i,j],y[i,j],0.0, a,k,w,d)
p[i,j] = waves.phi(x[i,j],y[i,j],z[i,j],0.0, a,k,w,d)
gradp[i,j] = waves.gradphi(x[i,j],y[i,j],z[i,j],0.0, a,k,w,d)[2]
# We can plot starting data
plot_j = int(ny/2)
fig = figure()
plot(x[:,plot_j], z[:,plot_j], color="blue", linewidth=2.5, linestyle="-", label="z")
plot(x[:,plot_j], gradp[:,plot_j], color="red", linewidth=2.5, linestyle="-", label="vz")
plot(x[:,plot_j], p[:,plot_j], color="green", linewidth=2.5, linestyle="-", label="phi")
legend(loc='best')
grid()
show()
close(fig)
# Compute the error in an arbitrary point
phi = zeros((nx,ny),dtype=float32)
i = int(nx/2)
j = int(ny/2)
xx = x[i,j]
yy = y[i,j]
zz = z[i,j]
pp = array([xx,yy,zz])
print('Testing direct method in the point ({0}, {1}, {2})'.format(pp[0],pp[1],pp[2]))
for I in range(0,nx):
for J in range(0,ny):
# Get phi from this point
XX = x[I,J]
YY = y[I,J]
ZZ = z[I,J]
PP = array([XX,YY,ZZ])
if((I,J) == (i,j)):
# if (I in range(i-1,i+2)) or (J in range(j-1,j+2)):
G,H = GH(PP,I,J,pp,nG,L,B,x,y,z,drx,dry,0.0, a,k,w,d)
else:
G = G_val(PP,pp)*dS
H = H_val(PP,pp)*dS
phi[i,j] = phi[i,j] - (p[I,J]*H[2] - gradp[I,J]*G)
# Get phi from the extended free surface
for II in range(-Nx,Nx+1):
for JJ in range(-Ny,Ny+1):
if (not II) and (not JJ):
# This is the computational domain
continue
XX = x[I,J] + II*L
YY = y[I,J] + JJ*B
ZZ = waves.z(XX,YY,0.0, a,k,w,d)
PP = array([XX,YY,ZZ])
Phi = waves.phi(XX,YY,ZZ,0.0, a,k,w,d)
gPhi = waves.gradphi(XX,YY,ZZ,0.0, a,k,w,d)[2]
phi[i,j] = phi[i,j] - (Phi*H_val(PP,pp)[2] - gPhi*G_val(PP,pp))*dS
# Correct phi
phi[i,j] = 2.0*phi[i,j]
print('Computed = {0}, analitic = {1}\n'.format(phi[i,j],p[i,j]))
# Compute the error along all the free surface
phi = zeros((nx,ny),dtype=float32)
error = 0.0
done = 0
print('Testing direct method in all the free surface')
for i in range(0,nx):
for j in range(0,ny):
if done != (100*(j + i*ny))/(nx*ny):
done = (100*(j + i*ny))/(nx*ny)
sys.stdout.write("{0}%...".format(done))
sys.stdout.flush()
xx = x[i,j]
yy = y[i,j]
zz = z[i,j]
pp = array([xx,yy,zz])
for I in range(0,nx):
for J in range(0,ny):
# Get phi from this point
XX = x[I,J]
YY = y[I,J]
ZZ = z[I,J]
PP = array([XX,YY,ZZ])
if((I,J) == (i,j)):
# if (I in range(i-1,i+2)) or (J in range(j-1,j+2)):
G,H = GH(PP,I,J,pp,nG,L,B,x,y,z,drx,dry,0.0, a,k,w,d)
else:
G = G_val(PP,pp)*dS
H = H_val(PP,pp)*dS
phi[i,j] = phi[i,j] - (p[I,J]*H[2] - gradp[I,J]*G)
# Get phi from the extended free surface
for II in range(-Nx,Nx+1):
for JJ in range(-Ny,Ny+1):
if (not II) and (not JJ):
# This is the computational domain
continue
XX = x[I,J] + II*L
YY = y[I,J] + JJ*B
ZZ = waves.z(XX,YY,0.0, a,k,w,d)
PP = array([XX,YY,ZZ])
Phi = waves.phi(XX,YY,ZZ,0.0, a,k,w,d)
gPhi = waves.gradphi(XX,YY,ZZ,0.0, a,k,w,d)[2]
phi[i,j] = phi[i,j] - (Phi*H_val(PP,pp)[2] - gPhi*G_val(PP,pp))*dS
# Correct phi
phi[i,j] = 2.0*phi[i,j]
error = error + (phi[i,j] - p[i,j])**2
error = sqrt(error / (nx*ny))
print('\nRoot mean square error = {0}\n'.format(error))
fig = figure()
plot(x[:,plot_j], p[:,plot_j], color="blue", linewidth=2.5, linestyle="-", label="analitic")
plot(x[:,plot_j], phi[:,plot_j], color="red", linewidth=2.5, linestyle="-", label="interpolated")
legend(loc='best')
grid()
show()
close(fig)
# Compute the BEM
GG = zeros((nx*ny, nx*ny), dtype=float32)
HH = -0.5 * array(identity(nx*ny),dtype=float32)
BB = zeros((nx*ny), dtype=float32)
error = 0.0
done = 0
print('Testing BEM in all the free surface')
for i in range(0,nx):
for j in range(0,ny):
if done != (100*(j + i*ny))/(nx*ny):
done = (100*(j + i*ny))/(nx*ny)
sys.stdout.write("{0}%...".format(done))
sys.stdout.flush()
xx = x[i,j]
yy = y[i,j]
zz = z[i,j]
pp = array([xx,yy,zz])
for I in range(0,nx):
for J in range(0,ny):
# Get phi from this point
XX = x[I,J]
YY = y[I,J]
ZZ = z[I,J]
PP = array([XX,YY,ZZ])
if((I,J) == (i,j)):
# if (I in range(i-1,i+2)) or (J in range(j-1,j+2)):
G,H = GH(PP,I,J,pp,nG,L,B,x,y,z,drx,dry,0.0, a,k,w,d)
else:
G = G_val(PP,pp)*dS
H = H_val(PP,pp)*dS
GG[j + i*ny,J + I*ny] = GG[j + i*ny,J + I*ny] - G
HH[j + i*ny,J + I*ny] = HH[j + i*ny,J + I*ny] - H[2]
# Get phi from the extended free surface
for II in range(-Nx,Nx+1):
for JJ in range(-Ny,Ny+1):
if (not II) and (not JJ):
# This is the computational domain
continue
XX = x[I,J] + II*L
YY = y[I,J] + JJ*B
ZZ = waves.z(XX,YY,0.0, a,k,w,d)
PP = array([XX,YY,ZZ])
Phi = waves.phi(XX,YY,ZZ,0.0, a,k,w,d)
gPhi = waves.gradphi(XX,YY,ZZ,0.0, a,k,w,d)[2]
BB[j + i*ny] = BB[j + i*ny] - (Phi*H_val(PP,pp)[2] - gPhi*G_val(PP,pp))*dS
[gPhi, residues, rank, s] = la.lstsq(GG, dot(HH,p.reshape(nx*ny)) + BB)
gPhi = gPhi.reshape(nx,ny)
if(rank < nx*ny):
print("Singular matrix G!.\n")
print("\tEffective rank of linear system matrix is %i (N = %i)\n" % (rank, nx*ny))
for i in range(0,nx):
for j in range(0,ny):
error = error + (gPhi[i,j] - gradp[i,j])**2
error = sqrt(error / (nx*ny))
print('\nRoot mean square error = {0}\n'.format(error))
fig = figure()
plot(x[:,plot_j], gradp[:,plot_j], color="blue", linewidth=2.5, linestyle="-", label="analitic")
plot(x[:,plot_j], gPhi[:,plot_j], color="red", linewidth=2.5, linestyle="-", label="interpolated")
legend(loc='best')
grid()
show()
close(fig)

View File

@ -0,0 +1,94 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
from numpy import *
from green import *
def z(x,y,t, a,k,w,d):
""" Returns free surface shape
@param x X coordinate
@param y Y coordinate
@param t Time instant
@param a List of waves amplitudes
@param k List of waves k
@param w List of waves omega
@param d List of waves lags.
@return free surface elevation
"""
Z = 0.0
for i in range(0,len(a)):
Z = Z + a[i]*sin(k[i]*x - w[i]*t + d[i])
return Z
def gradz(x,y,t, a,k,w,d):
""" Returns free surface shape gradient
@param x X coordinate
@param y Y coordinate
@param t Time instant
@param a List of waves amplitudes
@param k List of waves k
@param w List of waves omega
@param d List of waves lags.
@return free surface elevation
"""
gradZ = zeros((3), dtype=float32)
gradZ[2] = 1.0
for i in range(0,len(a)):
gradZ[0] = gradZ[0] + a[i]*k[i]*cos(k[i]*x - w[i]*t + d[i])
return gradZ
def phi(x,y,z,t, a,k,w,d):
""" Returns velocity potential
@param x X coordinate
@param y Y coordinate
@param z Free surface elevation
@param t Time instant
@param a List of waves amplitudes
@param k List of waves k
@param w List of waves omega
@param d List of waves lags.
@return Velocity potential
"""
p = 0.0
for i in range(0,len(a)):
p = p - a[i]*w[i]/k[i]*cos(k[i]*x - w[i]*t + d[i])*exp(k[i]*z)
return p
def gradphi(x,y,z,t, a,k,w,d):
""" Returns velocity potential gradient
@param x X coordinate
@param y Y coordinate
@param z Free surface elevation
@param t Time instant
@param a List of waves amplitudes
@param k List of waves k
@param w List of waves omega
@param d List of waves lags.
@return velocity potential gradient
"""
gradp = zeros((3), dtype=float32)
for i in range(0,len(a)):
gradp[0] = gradp[0] + a[i]*w[i]*sin(k[i]*x - w[i]*t + d[i])*exp(k[i]*z)
gradp[2] = gradp[2] - a[i]*w[i]*cos(k[i]*x - w[i]*t + d[i])*exp(k[i]*z)
return gradp