Generating Random Initial Guess for Nonlinear Problem

Asked by Derek

I'm working with an iteration method for solving nonlinear problems and would like to be able generate a random initial iterate as an attempt at a solution. I've been able to do this on the unit interval but would like to do the same on the unit square. Here's the code I am attempting to use:

import random
from dolfin import *
import sys

#Finite Element Set up
mesh = UnitSquare(64, 64)
V = FunctionSpace(mesh, 'CG', degree = 1)

#Construct an Initial Guess

class InitialConditions(Expression):
    def __init__(self):
        random.seed(10)
    def eval(self, values, x):
        values[0] = random.random()
 values[1] = random.random()
    def value_shape(self):
        return (2,)

uguess = InitialConditions()
uOld = Function(V)
uOld.interpolate(uguess)

I would like to be able to use uOld in my variational form to solve for the next iterate, but I get the following error:

Traceback (most recent call last):
  File "Random_Guess.py", line 22, in <module>
    uOld.interpolate(uguess)
RuntimeError: *** Error: Cannot interpolate functions of different ranks.

Ideally, I would also like to make my initial guess be zero on the boundary as well. Is there an easy mistake in my code or a better way to do this? Thanks in advance!

Question information

Language:
English Edit question
Status:
Solved
For:
DOLFIN Edit question
Assignee:
No assignee Edit question
Solved by:
Johan Hake
Solved:
Last query:
Last reply:
Revision history for this message
Best Johan Hake (johan-hake) said :
#1

On Tuesday January 17 2012 02:35:39 Derek wrote:
> New question #184943 on DOLFIN:
> https://answers.launchpad.net/dolfin/+question/184943
>
> I'm working with an iteration method for solving nonlinear problems and
> would like to be able generate a random initial iterate as an attempt at a
> solution. I've been able to do this on the unit interval but would like
> to do the same on the unit square. Here's the code I am attempting to
> use:
>
> import random
> from dolfin import *
> import sys
>
> #Finite Element Set up
> mesh = UnitSquare(64, 64)
> V = FunctionSpace(mesh, 'CG', degree = 1)
>
> #Construct an Initial Guess
>
> class InitialConditions(Expression):
> def __init__(self):
> random.seed(10)
> def eval(self, values, x):
> values[0] = random.random()
> values[1] = random.random()
> def value_shape(self):
> return (2,)
>
> uguess = InitialConditions()
> uOld = Function(V)
> uOld.interpolate(uguess)
>
> I would like to be able to use uOld in my variational form to solve for the
> next iterate, but I get the following error:
>
> Traceback (most recent call last):
> File "Random_Guess.py", line 22, in <module>
> uOld.interpolate(uguess)
> RuntimeError: *** Error: Cannot interpolate functions of different ranks.

The expression you are creating is of rank 1, it is vector valued and has two
values for each coordinate. For the interpolation to work out you need either
make the expression scalar valued or use a VectorFunctionSpace for V.

You can also just assign all the dofs directly:

  from numpy.random import rand
  uOld.vector()[:] = rand(len(uOld.vector()))

> Ideally, I would also like to make my initial guess be zero on the boundary
> as well. Is there an easy mistake in my code or a better way to do this?

You can create a DirichletBC and apply it to the dofs in the Function.

  left_bc = DirichletBC(V, 0, "near(x[0], 0)")
  left_bc.apply(uOld.vector())

Johan

> Thanks in advance!

Revision history for this message
Derek (olso4056) said :
#2

Thanks Johan Hake, that solved my question.

Revision history for this message
Derek (olso4056) said :
#3

I see the original problem now. The new formulation works like a charm! Thanks!