python 3

2017-06-07 Thread Nils Becker
hi,

i'm considering updating my scripts from 2.7 to python 3.4 or 3.6.
should i expect any problems? is fipy tested on py 3?

thanks!


0xF0A5C638.asc
Description: application/pgp-keys
___
fipy mailing list
fipy@nist.gov
http://www.ctcms.nist.gov/fipy
  [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]


Re: reaction-advection-diffusion; problems making the solution converge

2016-08-05 Thread Nils Becker
hi daniel, thanks for looking into this!


> Hi Nils,
> 
> It seems like the code is converging well as far as I can tell. For
> example, when I modify the sweep loop to be
> 
> 
> print
> print 'step: {0}'.format(tt)
> while res > 1e-9: #Solve.sweeps:
> res = eq.sweep(var=rho, dt=Solve.step,
> solver=Solve.customSolver)
> print res
> 
> 
> every step seems to converge in 5 steps to 1e-10.

ok. it seems that you have not changed the iteration, only added print
functions. so my code seems to be converging, yes?

that's also what i thought. however testing the solution externally, it
seems that the solution is not quite accurate (as time progresses, it
seems to get worse).

of course, this external test could be buggy -- however the fact that it
shows that lhs = rhs quite accurately in the beginning makes me think
that it could be correct.

> The non-linear residual only really tells you how well each step
> individually is converging. It seems like you were only using the very
> first non-linear residual, which uses the old value for the
> calculation, which doesn't tell you anything useful. 

so what sweep returns is basically A(n) * x(n-1) - b(n), yes? as far as
i can tell, i always collect the last one of these values in each step.
they do get small, i also see the convergence to below 1e-9 when i set
the tolerance that low.

> 
> One thing that I'm confused about is that it requires 5 sweeps to
> converge for a fully linear equation. Is it actually linear? I
> couldn't tell from the code.

yes. this also surprised me. the potential phi and the growth rate
lambda_ are of course non-linear functions of space. but all
coefficients are independent of the density, and the density rho should
be really appearing only linearly in the equation. so unless i
constructed the equation or the loop wrong, the system should really be
linear. no idea why it would require sweeps. do linear equations with an
implicit source term require sweeping? am i doing the sweep wrong?

n.







0xF0A5C638.asc
Description: application/pgp-keys
___
fipy mailing list
fipy@nist.gov
http://www.ctcms.nist.gov/fipy
  [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]


Re: reaction-advection-diffusion; problems making the solution converge

2016-08-05 Thread Nils Becker
>> I'm not sure if using ||lhs|| is a good way to normalize the residual.
>> Surely that could be very small. Is ||lhs - rhs|| getting smaller
>> without normalization?

if you don't see any obvious errors in building the solution in fipy, i
could continue poking around if i knew how to evaluate the various terms
of the solution and their errors at different times. i see methods
eq_diffprolif.justErrorvector, but i don't quite understand what exactly
this returns. is it lhs-rhs? what is justResidualVector? can i get those
for the individual terms on the rhs as well?

cheers, n.


0xF0A5C638.asc
Description: application/pgp-keys
___
fipy mailing list
fipy@nist.gov
http://www.ctcms.nist.gov/fipy
  [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]


Re: reaction-advection-diffusion; problems making the solution converge

2016-08-03 Thread Nils Becker

> I'm not sure if using ||lhs|| is a good way to normalize the residual.
> Surely that could be very small. Is ||lhs - rhs|| getting smaller
> without normalization?

ok, i was not very precise in my statement. actually i was doing this:

1. make a plot of lhs pointwise.
2. make a plot of lhs - rhs pointwise, on the same scale.

then compare the size of the deviations lhs-rhs. what i see is that the
absolute deviations lhs-rhs do increase over time and that they reach a
level over 10% of the lhs, at those points in the phase space where the
lhs is largest in magnitude

sorry for the confusion.

n.


0xF0A5C638.asc
Description: application/pgp-keys
___
fipy mailing list
fipy@nist.gov
http://www.ctcms.nist.gov/fipy
  [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]


Re: reaction-advection-diffusion; problems making the solution converge

2016-08-03 Thread Nils Becker
> Could you possible post your code so I can play around with it? I
> can't think offhand what could be the issue or exactly what the error
> is that you're calculating, it seems like the normalized residual or
> something. 

hi daniel, thanks for your reply. the way i was calculating the residual
is to export the solution on a grid, import that into mathematica,
interpolate in space and time and have mathematica calculate
||lhs-rhs|| / ||lhs|| where ||...|| is the L2 norm. what i saw was that
the relative error was low in the beginning but increased over time,
especially in places where the solution starts to grow exponentially.


i am sure this relative error can be gotten from fipy using
residualVector or some other methods of the terms but i have not been
able to understand the docs well enough to replicate that.

so i am posting pretty much the (streamlined but otherwise unchanged)
example script i am having trouble with below. h5py is needed only for
the export, you can comment that out if you dont export. Lambda3 is the
source term coefficient -- by increasing it's values the solution
becomes more rapidly growing and the errors also increase.

i hope the indentation survives emailing

cheers, n.



from __future__ import division
import fipy as fp
from fipy import numerix as nx
# the module for the bare numpy functions
# this is essentially numpy!
NX = nx.NUMERIX
from time import sleep


# this is where we are going to write results
import os
datadir = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
'pde_test_data/'
)
datadir = os.path.realpath(datadir)
try: os.mkdir(datadir)
except OSError: pass

# utility
def nsq(v):
return nx.dot(v, v)

class Domain(object):
upper = 300.
lower = 0
size = upper - lower

class Mesh(Domain):
def __init__(self):
delta = 1.5
Lx, Ly = (self.size,) * 2
dx, dy = (delta,) * 2
nx, ny = (self.size // delta,) * 2
self.mesh = fp.Grid2D(dx=dx, dy=dx, nx=nx, ny=ny, Lx=Lx, Ly=Ly)

# from Mma, the last iteration of the potential was this:

class Phi(object):
scale = 100.
x1, y1 = [100., 100]
x2, y2 = [180., 180]
s1 = 4.
s2 = 12.
dp = 3.
strength = 30.
sharpness_a = 120.
# the following should act on the position field x
# this should be a cell varable in fipy.
@classmethod
def itp(cls, z):
t = nx.tanh(z/cls.sharpness_a**2) + 1
return 0.5 * t
@classmethod
def scalephi(cls, x, y):
[d1, d2] = [(x-cls.x1)**2 + (y-cls.y1)**2,
(x-cls.x2)**2 + (y-cls.y2)**2]
[f2, f1] = [cls.itp(d1 - d2), cls.itp(d2 - d1)]
p1 = 0.5 * cls.s1 * d1 / cls.scale**2
p2 = 0.5 * cls.s2 * d2 / cls.scale**2 - cls.dp
return f1 * p1 + f2 * p2
@classmethod
def __call__(cls, x, y):
return cls.strength * cls.scalephi(x, y)

class Lambda3(object):
def __init__(self, curvature=None, direction=None, start=None):
if curvature is None: curvature = 0.2 / Domain.size**2
if direction is None: direction = nx.array([1, 1.])
direction /= nx.sqrt(nsq(nx.array(direction)))
if start is None: start = nx.array([0.,0])
max_pos = 0.5 * nx.sqrt(2) * Domain.size
max_ht = 1./2 * max_pos**2 * curvature # for 0 at the origin
max_ht = 0.1 * max_ht # tame the beast
(self.curvature, self.direction, self.max_pos, self.max_ht,
self.start) = (
curvature, direction, max_pos, max_ht, start)
def __call__(self, x, y):
distance2 = (NX.dot(self.direction,
(nx.array([x, y]).T - self.start).T) - self.max_pos)**2
lam = self.max_ht - 1./2 * self.curvature * distance2
return lam

class InitialRho(object):
'''Gaussian-like initial condition'''
c = [[100], [100]]
covm = NX.eye(2) * 30**2  # bare numpy
stm = NX.linalg.inv(covm)
Z = (2. * NX.linalg.det(covm))**(1./2)
@classmethod
def __call__(cls, x, y):
p = NX.array([x,y])
return  1. / cls.Z * NX.exp(-1./2 * NX.diag(
cls.stm.dot(p - cls.c).T.dot(p - cls.c)))

mesh = Mesh().mesh
x, y = mesh.cellCenters
x1d, y1d = x[:mesh.nx], y[::mesh.ny] # yes!


# diffusion
Dtensor = nx.eye(2) * 10.
# constant diff coeff fields
Dtensor = fp.CellVariable(mesh, 'dtensor', Dtensor)

# make the input fields
phi = fp.CellVariable(name=r'$\phi$', mesh=mesh, value=Phi()(x, y))
v = - phi.grad  # on the cells, not the faces.

lambda_ = fp.CellVariable(name=r'$\lambda$', mesh=mesh,
value=Lambda3(curvature=1./Domain.size**2, direction=[1.,-1],
start=[0.,Domain.size])(x, y))


# terms
def diff(DD):
# Correction actually needed? in any case it seems to work.
# list of diffusion coefficients of different orders
return fp.DiffusionTermCorrection(coeff=[DD,])
def drift(v):
return - fp.PowerLawConvectionTerm(coeff=v)
def prolif(lambda_):
# implicit = multiplies the var
return fp.Im

reaction-advection-diffusion; problems making the solution converge

2016-08-01 Thread Nils Becker
hi,

i scanned the list and the documentation but have not been able to make
this work properly yet:

i have a 2D pde of the form

\[

\partial_t \rho =  \nabla \cdot (\rho \nabla \phi) + D \nabla^2 \rho +
\lambda \rho

\]

where phi is a potential field and lambda is a source field, both are
constant in time and smoothly varying in space.

i have been solving this with fipy, using

DiffusionTermCorrection(coeff=[D,]) for the diffusion
PowerLawConvectionTerm(coeff=v ) where v = -phi.grad for the advection
ImplicitSourceTerm(coeff=lambda) for the source

the boundary conditions are either no-flux or dirichlet. i think
advection is dominant, although i can't say i have actually tried to
quantify that.

i am testing the solution by subtracting the rhs and lhs of the equation
and comparing that to \partial_t \rho in magnitude. i am having trouble
making this error smaller than around 10%: at points where the density
grows strongly, the solution deviates.

at the moment i am using a loop like this:

for (st, stnext) in zip(Solve.sample_t, Solve.sample_t[1:]):
for tt in nx.arange(st, stnext, Solve.step):
rho.updateOld()
res = 1.
while res > Solve.tolerance:
res = eq.sweep(var=rho, dt=Solve.step)

i've played around with making the mesh smaller -- did not seem to make
any difference; reducing the tolerance -- some effect, and reducing the
temporal step size, which did not help much.

should i be doing something differently?

thanks for any help!

n.
___
fipy mailing list
fipy@nist.gov
http://www.ctcms.nist.gov/fipy
  [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]