Hello
I am currently using Fenics and Leopart to model the evolution of ice crystal orientation in a stokes velocity field. I would like to be able to manually update the properties carried by the Leopart particles at each timestep using a model I have implemented in numpy. At the moment I have this working by extracting the properties, modifying them and then creating new particles (with the same location) at each timestep. However I was wondering if it is possible to more elegantly assign new values to the particle properties. This approach would I assume be more suited to parallelization.
Iâve attached a minimal example of how Iâm currently updating particle properties:
from fenics import*
from mshr import *
import leopart as lp
import numpy as np
nt=10
dt = 0.01
npart = 15
npmin=12
npmax=20
mesh = UnitSquareMesh(20,20)
#Velocity
V = VectorFunctionSpace(mesh, "DG", 1)
P = FunctionSpace(mesh,"DG",1)
u = Function(V)
u.assign(Expression(("x[1]","0.0"),degree=1))
(ux,uy)=split(u)
# Initialize particles
x = lp.RandomCell(mesh).generate(npart)
def numpy2particle(xnew,q,r):
return lp.particles(xnew,[q, r], mesh)
def particle2numpy(p):
x = p.positions()
a = np.array(p.get_property(1))
b = np.array(p.get_property(2))
return x,a,b
# Initial particle
a = np.zeros(x.shape[0])
b = np.zeros(x.shape[0])
p = numpy2particle(x,a,b)
# Functions for interpolating
a_df = Function(P)
b_df = Function(P)
for it in range(nt):
#Advect particles
ap = lp.advect_rk3(p, V, u, "open")
ap.do_step(dt)
#Add delete
AD = lp.AddDelete(p,npmin,npmax,[a_df,b_df])
AD.do_sweep()
x,a,b = particle2numpy(p)
## Change properties
a= 2*b
b= 5. + a ##just as a minimal example
# Update particle by creating a new particle
p = numpy2particle(x,a,b)
# Create fenics functions for add delete
lstsqa = lp.l2projection(p,P,1)
lstsqa.project(a_df)
lstsqb = lp.l2projection(p,P,1)
lstsqb.project(b_df)
Thanks for the help