def _create_function_spaces(t, T, a, b, fineness_t, fineness_x): """Here we create the function spaces involved (and also the mesh as well). """ nx = round((b - a) / fineness_x) # number of space steps ### Define periodic boundary class PeriodicBoundary(fc.SubDomain): def inside(self, x, on_boundary): return bool(x[0] < fc.DOLFIN_EPS and x[0] > -fc.DOLFIN_EPS and on_boundary) # Map right boundary to left boundary def map(self, x, y): y[0] = x[0] - (b - a) ### Create mesh and define function spaces mesh = fc.IntervalMesh(nx, a, b) F_ele = fc.FiniteElement("CG", mesh.ufl_cell(), 1) V = fc.FunctionSpace(mesh, F_ele, constrained_domain=PeriodicBoundary()) W = fc.FunctionSpace(mesh, fc.MixedElement([F_ele, F_ele]), constrained_domain=PeriodicBoundary()) return V, W, mesh
def create_simple_mesh(self): print('Creating simple mesh') nx = ny = self.mesh_density if self.dimension == 1: self.mesh = fe.IntervalMesh(nx, self.x_left, self.x_right) if self.dimension == 2: self.mesh = fe.UnitSquareMesh(nx, ny)
def dynamic_solver_func(ncells=10, # количество узлов на заданном итервале init_time=0, # начальный момент времени end_time=10, # конечный момент времени dxdphi=1, # производная от потенциала по х dydphi=1, # производня от потенциала по у x0=0, # начальное положение по оси х vx0=1, # проекция начальной скорости на ось х y0=0, # начальное положение по оси у vy0=1): # проекция начальной скорости на ось у """ Функция на вход которой подается производная от потенциала гравитационного поля, возвращающая координаты смещенных материальных точек (частиц). """ # генерация сетки на заданном интервале времени mesh = fen.IntervalMesh(ncells, 0, end_time-init_time) welm = fen.MixedElement([fen.FiniteElement('Lagrange', fen.interval, 2), fen.FiniteElement('Lagrange', fen.interval, 2), fen.FiniteElement('Lagrange', fen.interval, 2), fen.FiniteElement('Lagrange', fen.interval, 2)]) # генерация функционального рростаанства W = fen.FunctionSpace(mesh, welm) # постановка начальных условий задачи bcsys = [fen.DirichletBC(W.sub(0), fen.Constant(x0), 'near(x[0], 0)'), fen.DirichletBC(W.sub(1), fen.Constant(vx0), 'near(x[0], 0)'), fen.DirichletBC(W.sub(2), fen.Constant(y0), 'near(x[0], 0)'), fen.DirichletBC(W.sub(3), fen.Constant(vy0), 'near(x[0], 0)')] # опееделение тестовых функций для решения задачи up = fen.Function(W) x_cor, v_x, y_cor, v_y = fen.split(up) v1, v2, v3, v4 = fen.split(fen.TestFunction(W)) # постановка задачи drdt = v; dvdt = - grad(phi) в проекциях на оси системы координат weak_form = (x_cor.dx(0) - v_x) * v1 * fen.dx + (v_x.dx(0) + dxdphi) * v2 * fen.dx \ + (y_cor.dx(0) - v_y) * v3 * fen.dx + (v_y.dx(0) + dydphi) * v4 * fen.dx # решние поставленной задачи fen.solve(weak_form == 0, up, bcs=bcsys) # определение момента времени time = fen.Point(end_time - init_time) # расчет координат и скоростей x_end_time = up(time.x())[0] vx_end_time = up(time.x())[1] y_end_time = up(time.x())[2] vy_end_time = up(time.x())[3] return x_end_time, y_end_time, vx_end_time, vy_end_time
def wrapper1D(par, nGridPoints, N_PN, boundaryFilePrefix, solutionFolder): #-------- load mesh -------- mesh = fe.IntervalMesh(nGridPoints - 1, par['domain']['zMin'], par['domain']['zMax']) ds = defineBoundaryMarkers1D(mesh, par['domain']['zMin'], par['domain']['zMax']) u = solvePN2nd(par, N_PN, mesh, boundaryFilePrefix, ds) #fe.plot(u[0]) # first moment: u0 = int_{4pi} I * b0 dOmega, b0 = sqrt(1 / 4 / pi) # radiative energy: phi = int_{4pi} I dOmega radiativeEnergy = np.sqrt(4 * np.pi) * u[0].compute_vertex_values() createFolder(solutionFolder) sio.savemat('%sradiativeEnergy_P%d2nd_n_%d.mat'%(solutionFolder, N_PN, nGridPoints), {'radiativeEnergy': radiativeEnergy, 'points': mesh.coordinates(), 'connectivityList': mesh.cells()}) return u
def runModelButt(self): if len(markers) > 0: try: self.runButt.setEnabled(False) self.dr = float(self.sptlResLineEdit.text()) # dr = 150 self.pauseButt.setEnabled(True) interpolateData(True, self.dr,{}) ########################################### ### INTERPOLATE DATA SO EVEN INTERVAL ### ########################################### ''' Interpolating data at an even interval so the data points align with the invterval mesh. ''' self.thickness1dInterp = interp1d(thickness.distanceData, thickness.pathData) self.bed1dInterp = interp1d(bed.distanceData, bed.pathData) self.surface1dInterp = interp1d(surface.distanceData, surface.pathData) self.smb1dInterp = interp1d(smb.distanceData, smb.pathData) self.velocity1dInterp = interp1d(velocity.distanceData, velocity.pathData) self.t2m1dInterp = interp1d(t2m.distanceData, t2m.pathData) # N is the number of total data points including the last # Data points on interval [0, N*dr] inclusive on both ends self.N = int(np.floor(bed.distanceData[-1] / float(self.dr))) # length of path / resolution self.x = np.arange(0, (self.N + 1) * self.dr, self.dr) # start point, end point, number of segments. END POINT NOT INCLUDED! self.mesh = fc.IntervalMesh(self.N, 0, self.dr * self.N) # number of cells, start point, end point self.thicknessModelData = self.thickness1dInterp(self.x) self.bedModelData = self.bed1dInterp(self.x) self.surfaceModelData = self.surface1dInterp(self.x) self.smbModelData = self.smb1dInterp(self.x) self.velocityModelData = self.velocity1dInterp(self.x) self.t2mModelData = self.t2m1dInterp(self.x) self.THICKLIMIT = 10. # Ice is never less than this thick self.H = self.surfaceModelData - self.bedModelData self.surfaceModelData[self.H <= self.THICKLIMIT] = self.bedModelData[self.H <= self.THICKLIMIT] # FIXME the intervalMesh is consistantly 150 between each datapoint this not true for the data being sent self.hdf_name = '.data/latest_profile.h5' self.hfile = fc.HDF5File(self.mesh.mpi_comm(), self.hdf_name, "w") self.V = fc.FunctionSpace(self.mesh, "CG", 1) self.functThickness = fc.Function(self.V, name="Thickness") self.functBed = fc.Function(self.V, name="Bed") self.functSurface = fc.Function(self.V, name="Surface") self.functSMB = fc.Function(self.V, name='SMB') self.functVelocity = fc.Function(self.V, name='Velocity') self.functT2m = fc.Function(self.V, name='T2m') surface.pathPlotItem.setData(self.x, self.surfaceModelData) pg.QtGui.QApplication.processEvents() self.functThickness.vector()[:] = self.thicknessModelData self.functBed.vector()[:] = self.bedModelData self.functSurface.vector()[:] = self.surfaceModelData self.functSMB.vector()[:] = self.smbModelData self.functVelocity.vector()[:] = self.velocityModelData self.functT2m.vector()[:] = self.t2mModelData self.hfile.write(self.functThickness.vector(), "/thickness") self.hfile.write(self.functBed.vector(), "/bed") self.hfile.write(self.functSurface.vector(), "/surface") self.hfile.write(self.functSMB.vector(), "/smb") self.hfile.write(self.functVelocity.vector(), "/velocity") self.hfile.write(self.functT2m.vector(), "/t2m") self.hfile.write(self.mesh, "/mesh") self.hfile.close() self.runModel() except ValueError: print 'ERROR: Must have valid spatial resolution.'
import matplotlib.pyplot as plt import fenics as fe from ufl import bessel_I mesh = fe.IntervalMesh(100, 0, 10) V = fe.FunctionSpace(mesh, 'P', 1) x = fe.SpatialCoordinate(mesh) bs = bessel_I(0, x[0]) expr = fe.Expression('cos(x[0]*b)', b=10, element=V.ufl_element()) expr_bessel = expr * bs proj_expr = fe.project(expr_bessel, V) # fe.plot(proj_expr) # plt.show() # class MyExpression(fe.UserExpression): # def eval(self, values, x): # values[0] = x[0] ** 2 # def value_shape(self): # return () # expr = MyExpression(degree=1) # class InitialConditions(fe.UserExpression): # def __init__(self, **kwargs): # # random.seed(2 + MPI.rank(MPI.comm_world)) # super().__init__(**kwargs) # def eval(self, values, x): # values[0] = 0.63 # def value_shape(self):
def dataToHDF5(fileName, distanceData, thicknessPathData, bedPathData, surfacePathData, smbPathData, velocityPathData, t2mPathData, widthData, midFlowline, flowlines, resolution=1000): # Create interps for each of our variables thickness1dInterpAvg = interp1d(distanceData, thicknessPathData[1]) bed1dInterpAvg = interp1d(distanceData, bedPathData[1]) surface1dInterpAvg = interp1d(distanceData, surfacePathData[1]) smb1dInterpAvg = interp1d(distanceData, smbPathData[1]) velocity1dInterpAvg = interp1d(distanceData, velocityPathData[1]) t2m1dInterpAvg = interp1d(distanceData, t2mPathData[1]) thickness1dInterp = interp1d(distanceData, thicknessPathData[0]) bed1dInterp = interp1d(distanceData, bedPathData[0]) surface1dInterp = interp1d(distanceData, surfacePathData[0]) smb1dInterp = interp1d(distanceData, smbPathData[0]) velocity1dInterp = interp1d(distanceData, velocityPathData[0]) t2m1dInterp = interp1d(distanceData, t2mPathData[0]) width1dInterp = interp1d(distanceData, widthData) midFlowlineXData = [] midFlowlineYData = [] shearMargin0XData = [] shearMargin1XData = [] shearMargin0YData = [] shearMargin1YData = [] for i in range(len(midFlowline)): midFlowlineXData.append(midFlowline[i][0]) midFlowlineYData.append(midFlowline[i][1]) shearMargin0XData.append(flowlines[0][i][0]) shearMargin0YData.append(flowlines[0][i][1]) shearMargin1XData.append(flowlines[1][i][0]) shearMargin1YData.append(flowlines[1][i][1]) midFlowlineX1dInterp = interp1d(distanceData, midFlowlineXData) midFlowlineY1dInterp = interp1d(distanceData, midFlowlineYData) shearMargin0X1dInterp = interp1d(distanceData, shearMargin0XData) shearMargin0Y1dInterp = interp1d(distanceData, shearMargin0YData) shearMargin1X1dInterp = interp1d(distanceData, shearMargin1XData) shearMargin1Y1dInterp = interp1d(distanceData, shearMargin1YData) numberOfPoints = int(np.floor(distanceData[-1] / float(resolution))) x = np.arange(0, (numberOfPoints + 1) * resolution, resolution) mesh = fc.IntervalMesh(numberOfPoints, 0, resolution * numberOfPoints) thicknessModelData = thickness1dInterp(x) bedModelData = bed1dInterp(x) surfaceModelData = surface1dInterp(x) smbModelData = smb1dInterp(x) velocityModelData = velocity1dInterp(x) t2mModelData = t2m1dInterp(x) widthModelData = width1dInterp(x) midFlowlineXModelData = midFlowlineX1dInterp(x) midFlowlineYModelData = midFlowlineY1dInterp(x) shearMargin0XModelData = shearMargin0X1dInterp(x) shearMargin0YModelData = shearMargin0Y1dInterp(x) shearMargin1XModelData = shearMargin1X1dInterp(x) shearMargin1YModelData = shearMargin1Y1dInterp(x) thicknessModelDataAvg = thickness1dInterpAvg(x) bedModelDataAvg = bed1dInterpAvg(x) surfaceModelDataAvg = surface1dInterpAvg(x) smbModelDataAvg = smb1dInterpAvg(x) velocityModelDataAvg = velocity1dInterpAvg(x) t2mModelDataAvg = t2m1dInterpAvg(x) H = surfaceModelData - bedModelData HAvg = surfaceModelDataAvg - bedModelDataAvg surfaceModelData[H <= thklim] = bedModelData[H <= thklim] surfaceModelDataAvg[HAvg <= thklim] = bedModelDataAvg[HAvg <= thklim] fileName = '.data/' + fileName hfile = fc.HDF5File(mesh.mpi_comm(), '.data/latestProfile.h5', "w") profileFile = fc.HDF5File(mesh.mpi_comm(), str(fileName), "w") V = fc.FunctionSpace(mesh, "CG", 1) functThickness = fc.Function(V, name="Thickness") functBed = fc.Function(V, name="Bed") functSurface = fc.Function(V, name="Surface") functSMB = fc.Function(V, name="SMB") functVelocity = fc.Function(V, name="Velocity") functT2m = fc.Function(V, name="t2m") functWidth = fc.Function(V, name="width") functMidXValues = fc.Function(V, name='midX') functMidYValues = fc.Function(V, name='midY') functShear0XValues = fc.Function(V, name='Shear_0_X') functShear0YValues = fc.Function(V, name='Shear_0_Y') functShear1XValues = fc.Function(V, name='Shear_1_X') functShear1YValues = fc.Function(V, name='Shear_1_Y') functThicknessAvg = fc.Function(V, name="ThicknessAvg") functBedAvg = fc.Function(V, name="BedAvg") functSurfaceAvg = fc.Function(V, name="SurfaceAvg") functSMBAvg = fc.Function(V, name="SMBAvg") functVelocityAvg = fc.Function(V, name="VelocityAvg") functT2mAvg = fc.Function(V, name="t2mAvg") functThickness.vector()[:] = thicknessModelData functBed.vector()[:] = bedModelData functSurface.vector()[:] = surfaceModelData functSMB.vector()[:] = smbModelData functVelocity.vector()[:] = velocityModelData functT2m.vector()[:] = t2mModelData functWidth.vector()[:] = widthModelData functMidXValues.vector()[:] = midFlowlineXModelData functMidYValues.vector()[:] = midFlowlineYModelData functShear0XValues.vector()[:] = shearMargin0XModelData functShear0YValues.vector()[:] = shearMargin0YModelData functShear1XValues.vector()[:] = shearMargin1XModelData functShear1YValues.vector()[:] = shearMargin1YModelData functThicknessAvg.vector()[:] = thicknessModelDataAvg functBedAvg.vector()[:] = bedModelDataAvg functSurfaceAvg.vector()[:] = surfaceModelDataAvg functSMBAvg.vector()[:] = smbModelDataAvg functVelocityAvg.vector()[:] = velocityModelDataAvg functT2mAvg.vector()[:] = t2mModelDataAvg hfile.write(functThickness.vector(), "/thickness") hfile.write(functBed.vector(), "/bed") hfile.write(functSurface.vector(), "/surface") hfile.write(functSMB.vector(), "/smb") hfile.write(functVelocity.vector(), "/velocity") hfile.write(functT2m.vector(), "/t2m") hfile.write(functThicknessAvg.vector(), "/thicknessAvg") hfile.write(functBedAvg.vector(), "/bedAvg") hfile.write(functSurfaceAvg.vector(), "/surfaceAvg") hfile.write(functSMBAvg.vector(), "/smbAvg") hfile.write(functVelocityAvg.vector(), "/velocityAvg") hfile.write(functT2mAvg.vector(), "/t2mAvg") hfile.write(functWidth.vector(), "/width") hfile.write(functMidYValues.vector(), "/Mid_y") hfile.write(functMidXValues.vector(), "/Mid_x") hfile.write(functShear0XValues.vector(), "/Shear_0_x") hfile.write(functShear0YValues.vector(), "/Shear_0_y") hfile.write(functShear1XValues.vector(), "/Shear_1_x") hfile.write(functShear1YValues.vector(), "/Shear_1_y") hfile.write(mesh, "/mesh") profileFile.write(functThickness.vector(), "/thickness") profileFile.write(functBed.vector(), "/bed") profileFile.write(functSurface.vector(), "/surface") profileFile.write(functSMB.vector(), "/smb") profileFile.write(functVelocity.vector(), "/velocity") profileFile.write(functT2m.vector(), "/t2m") profileFile.write(functWidth.vector(), "/width") profileFile.write(functMidYValues.vector(), "/Mid_y") profileFile.write(functMidXValues.vector(), "/Mid_x") profileFile.write(functShear0XValues.vector(), "/Shear_0_x") profileFile.write(functShear0YValues.vector(), "/Shear_0_y") profileFile.write(functShear1XValues.vector(), "/Shear_1_x") profileFile.write(functShear1YValues.vector(), "/Shear_1_y") profileFile.write(mesh, "/mesh") profileFile.write(functThicknessAvg.vector(), "/thicknessAvg") profileFile.write(functBedAvg.vector(), "/bedAvg") profileFile.write(functSurfaceAvg.vector(), "/surfaceAvg") profileFile.write(functSMBAvg.vector(), "/smbAvg") profileFile.write(functVelocityAvg.vector(), "/velocityAvg") profileFile.write(functT2mAvg.vector(), "/t2mAvg") hfile.close() profileFile.close()
def discretize(self): """Builds function space, call again after introducing constraints""" # FEniCS interface self.mesh = fn.IntervalMesh(self.N, self.x0_scaled, self.x1_scaled) # http://www.femtable.org/ # Argyris* ARG # Arnold-Winther* AW # Brezzi-Douglas-Fortin-Marini* BDFM # Brezzi-Douglas-Marini BDM # Bubble B # Crouzeix-Raviart CR # Discontinuous Lagrange DG # Discontinuous Raviart-Thomas DRT # Hermite* HER # Lagrange CG # Mardal-Tai-Winther* MTW # Morley* MOR # Nedelec 1st kind H(curl) N1curl # Nedelec 2nd kind H(curl) N2curl # Quadrature Q # Raviart-Thomas RT # Real R # construct test and trial function space from elements # spanned by Lagrange polynomials for the pyhsical variables of # potential and concentration and global elements with a single degree # of freedom ('Real') for constraints. # For an example of this approach, refer to # https://fenicsproject.org/docs/dolfin/latest/python/demos/neumann-poisson/demo_neumann-poisson.py.html # For another example on how to construct and split function spaces # for solving coupled equations, refer to # https://fenicsproject.org/docs/dolfin/latest/python/demos/mixed-poisson/demo_mixed-poisson.py.html P = fn.FiniteElement('Lagrange', fn.interval, 3) R = fn.FiniteElement('Real', fn.interval, 0) elements = [P] * (1 + self.M) + [R] * self.K H = fn.MixedElement(elements) self.W = fn.FunctionSpace(self.mesh, H) # solution functions self.w = fn.Function(self.W) # set initial values if available P = fn.FunctionSpace(self.mesh, 'P', 1) dof2vtx = fn.vertex_to_dof_map(P) if self.ui0 is not None: x = np.linspace(self.x0_scaled, self.x1_scaled, self.ui0.shape[0]) ui0 = scipy.interpolate.interp1d(x, self.ui0) # use linear interpolation on mesh self.u0_func = fn.Function(P) self.u0_func.vector()[:] = ui0(self.X)[dof2vtx] fn.assign(self.w.sub(0), fn.interpolate(self.u0_func, self.W.sub(0).collapse())) if self.ni0 is not None: x = np.linspace(self.x0_scaled, self.x1_scaled, self.ni0.shape[1]) ni0 = scipy.interpolate.interp1d(x, self.ni0) self.p0_func = [fn.Function(P)] * self.ni0.shape[0] for k in range(self.ni0.shape[0]): self.p0_func[k].vector()[:] = ni0(self.X)[k, :][dof2vtx] fn.assign( self.w.sub(1 + k), fn.interpolate(self.p0_func[k], self.W.sub(k + 1).collapse())) # u represents voltage , p concentrations uplam = fn.split(self.w) self.u, self.p, self.lam = (uplam[0], [*uplam[1:(self.M + 1)]], [*uplam[(self.M + 1):]]) # v, q and mu represent respective test functions vqmu = fn.TestFunctions(self.W) self.v, self.q, self.mu = (vqmu[0], [*vqmu[1:(self.M + 1)]], [*vqmu[(self.M + 1):]])
def __init__(self, L, ne, r0, Q0, E, h0, theta, dt, degA=1, degQ=1): # -- Setup domain self.L = L self.ne = ne self.dt = dt self.mesh = fe.IntervalMesh(ne, 0, L) QE = fe.FiniteElement("Lagrange", cell=self.mesh.ufl_cell(), degree=degQ) AE = fe.FiniteElement("Lagrange", cell=self.mesh.ufl_cell(), degree=degA) ME = fe.MixedElement([AE, QE]) # -- Setup functionspaces self.V = fe.FunctionSpace(self.mesh, ME) self.V_A = self.V.sub(0) self.V_Q = self.V.sub(1) (self.v1, self.v2) = fe.TestFunctions(self.V) self.dv1 = fe.grad(self.v1)[0] self.dv2 = fe.grad(self.v2)[0] self.E = E self.h0 = h0 self.beta = E * h0 * np.sqrt(np.pi) self.A0 = np.pi * r0**2 self.Q0 = Q0 self.U0 = fe.Function(self.V) self.Un = fe.Function(self.V) # -- Setup initial conditions self.U0.assign(fe.Expression(('A0', 'Q0'), A0=self.A0, Q0=Q0, degree=1)) self.Un.assign(fe.Expression(('A0', 'Q0'), A0=self.A0, Q0=Q0, degree=1)) (self.u01, self.u02) = fe.split(self.U0) (self.un1, self.un2) = fe.split(self.Un) self.du01 = fe.grad(self.u01)[0] self.du02 = fe.grad(self.u02)[0] self.dun1 = fe.grad(self.un1)[0] self.dun2 = fe.grad(self.un2)[0] (self.W1_initial, self.W2_initial) = self.getCharacteristics(self.A0, self.Q0) # -- Setup weakform terms B0 = self.getB(self.u01, self.u02) Bn = self.getB(self.un1, self.un2) H0 = self.getH(self.u01, self.u02) Hn = self.getH(self.un1, self.un2) HdUdz0 = matMult(H0, [self.du01, self.du02]) HdUdzn = matMult(Hn, [self.dun1, self.dun2]) # -- Setup weakform wf = -self.un1 * self.v1 - self.un2 * self.v2 wf += self.u01 * self.v1 + self.u02 * self.v2 wf += -dt * theta * (HdUdzn[0] + Bn[0]) * self.v1 - dt * theta * ( HdUdzn[1] + Bn[1]) * self.v2 wf += -dt * (1 - theta) * (HdUdz0[0] + B0[0]) * self.v1 - dt * ( 1 - theta) * (HdUdz0[1] + B0[1]) * self.v2 wf = wf * fe.dx self.wf = wf self.J = fe.derivative(wf, self.Un, fe.TrialFunction(self.V))
# -- Time domain theta = 0.5 nt = 1000 T = 2*0.165 nt = 1e3 time = np.linspace(0,(T/2+(0.25-0.165)),int(nt)) dt = time[1]-time[0] time = np.array(time) Pin = 2e4*np.sin(2*np.pi*time/T) * np.heaviside(T/2-time,1) Ain = (Pin*A0/beta+np.sqrt(A0))**2; # -- Spatial domain ne = 2**7 L = 15 mesh = fe.IntervalMesh(int(ne),0,L) degQ = 1 degA = 1 QE = fe.FiniteElement("Lagrange", cell=mesh.ufl_cell(), degree=degQ) AE = fe.FiniteElement("Lagrange", cell=mesh.ufl_cell(), degree=degA) ME = fe.MixedElement([AE,QE]) V = fe.FunctionSpace(mesh,ME) V_A = V.sub(0) V_Q = V.sub(1) (v1,v2) = fe.TestFunctions(V) dv1 = fe.grad(v1)[0] dv2 = fe.grad(v2)[0] (u1,u2) = fe.TrialFunctions(V) U0 = fe.Function(V) U0.assign( fe.Expression( ( 'A0', 'Q0' ) , A0=A0, Q0=Q0, degree=1 ) ) Un = fe.Function(V)
def xest_implement_1d_myosin(self): #Parameters total_time = 10.0 number_of_time_steps = 1000 # delta_t = fenics.Constant(total_time/number_of_time_steps) delta_t = total_time / number_of_time_steps nx = 1000 domain_size = 1.0 b = fenics.Constant(6.0) k = fenics.Constant(0.5) z_1 = fenics.Constant(-10.5) #always negative # z_1 = fenics.Constant(0.0) #always negative z_2 = 0.1 # always positive xi_0 = fenics.Constant(1.0) #always positive xi_1 = fenics.Constant(1.0) #always positive xi_2 = 0.001 #always positive xi_3 = 0.0001 #always negative d = fenics.Constant(0.15) alpha = fenics.Constant(1.0) c = fenics.Constant(0.1) # Sub domain for Periodic boundary condition class PeriodicBoundary(fenics.SubDomain): # Left boundary is "target domain" G def inside(self, x, on_boundary): return bool(-fenics.DOLFIN_EPS < x[0] < fenics.DOLFIN_EPS and on_boundary) def map(self, x, y): y[0] = x[0] - 1 periodic_boundary_condition = PeriodicBoundary() #Set up finite elements mesh = fenics.IntervalMesh(nx, 0.0, 1.0) vector_element = fenics.FiniteElement('P', fenics.interval, 1) single_element = fenics.FiniteElement('P', fenics.interval, 1) mixed_element = fenics.MixedElement(vector_element, single_element) V = fenics.FunctionSpace( mesh, mixed_element, constrained_domain=periodic_boundary_condition) # V = fenics.FunctionSpace(mesh, mixed_element) v, r = fenics.TestFunctions(V) full_trial_function = fenics.Function(V) u, rho = fenics.split(full_trial_function) full_trial_function_n = fenics.Function(V) u_n, rho_n = fenics.split(full_trial_function_n) u_initial = fenics.Constant(0.0) # rho_initial = fenics.Expression('1.0*sin(pi*x[0])*sin(pi*x[0])+1.0/k0', degree=2,k0 = k) rho_initial = fenics.Expression('1/k0', degree=2, k0=k) u_n = fenics.interpolate(u_initial, V.sub(0).collapse()) rho_n = fenics.interpolate(rho_initial, V.sub(1).collapse()) # perturbation = np.zeros(rho_n.vector().size()) # perturbation[:int(perturbation.shape[0]/2)] = 1.0 rho_n.vector().set_local( np.array(rho_n.vector()) + 1.0 * (0.5 - np.random.random(rho_n.vector().size()))) # u_n.vector().set_local(np.array(u_n.vector())+4.0*(0.5-np.random.random(u_n.vector().size()))) fenics.assign(full_trial_function_n, [u_n, rho_n]) u_n, rho_n = fenics.split(full_trial_function_n) F = (u * v * fenics.dx - u_n * v * fenics.dx + delta_t * (b + (z_1 * rho) / (1 + z_2 * rho) * c * xi_1) * u.dx(0) * v.dx(0) * fenics.dx - delta_t * (z_1 * rho) / (1 + z_2 * rho) * c * c * xi_2 / 2.0 * u.dx(0) * u.dx(0) * v.dx(0) * fenics.dx + delta_t * (z_1 * rho) / (1 + z_2 * rho) * c * c * c * xi_3 / 6.0 * u.dx(0) * u.dx(0) * u.dx(0) * v.dx(0) * fenics.dx - delta_t * z_1 * rho / (1 + z_2 * rho) * xi_0 * v.dx(0) * fenics.dx + u.dx(0) * v.dx(0) * fenics.dx - u_n.dx(0) * v.dx(0) * fenics.dx + rho * r * fenics.dx - rho_n * r * fenics.dx - rho * u * r.dx(0) * fenics.dx + rho * u_n * r.dx(0) * fenics.dx + delta_t * d * rho.dx(0) * r.dx(0) * fenics.dx + delta_t * k * fenics.exp(alpha * u.dx(0)) * rho * r * fenics.dx - delta_t * r * fenics.dx + delta_t * c * u.dx(0) * r * fenics.dx) vtkfile_rho = fenics.File( os.path.join(os.path.dirname(__file__), 'output', 'myosin_2d', 'solution_rho.pvd')) vtkfile_u = fenics.File( os.path.join(os.path.dirname(__file__), 'output', 'myosin_2d', 'solution_u.pvd')) # rho_0 = fenics.Expression(((('0.0'),('0.0'),('0.0')),('sin(x[0])')), degree=1 ) # full_trial_function_n = fenics.project(rho_0, V) # print('initial u and rho') # print(u_n.vector()) # print(rho_n.vector()) time = 0.0 not_initialised = True plt.figure() for time_index in range(number_of_time_steps): # Update current time time += delta_t # Compute solution fenics.solve(F == 0, full_trial_function) # Save to file and plot solution vis_u, vis_rho = full_trial_function.split() plt.subplot(311) fenics.plot(vis_u, color='blue') plt.ylim(-0.5, 0.5) plt.subplot(312) fenics.plot(-vis_u.dx(0), color='blue') plt.ylim(-2, 2) plt.title('actin density change') plt.subplot(313) fenics.plot(vis_rho, color='blue') plt.title('myosin density') plt.ylim(0, 7) plt.tight_layout() if not_initialised: animation_camera = celluloid.Camera(plt.gcf()) not_initialised = False animation_camera.snap() print('time is') print(time) # plt.savefig(os.path.join(os.path.dirname(__file__),'output','this_output_at_time_' + '{:04d}'.format(time_index) + '.png')) # print('this u and rho') # print(np.array(vis_u.vector())) # print(np.array(vis_rho.vector())) # vtkfile_rho << (vis_rho, time) # vtkfile_u << (vis_u, time) full_trial_function_n.assign(full_trial_function) animation = animation_camera.animate() animation.save( os.path.join(os.path.dirname(__file__), 'output', 'myosin_1D.mp4'))
def onButtonPress(event): global line_points_x, line_points_y if event.inaxes is not None: ax = event.inaxes if ax == axarr[1] and event.button == 1: # print('button=%d, x=%d, y=%d, xdata=%f, ydata=%f' \ # %(event.button, event.x, event.y, event.xdata, event.ydata)) line_points_x.append(event.xdata) line_points_y.append(event.ydata) line.set_xdata(line_points_x) line.set_ydata(line_points_y) f.canvas.draw() # This was supposed to get the margins and plot them, but it isn't working. """ xml,yml,xmr,ymr = get_margins(event.xdata,event.ydata) print event.xdata,event.ydata,xml,yml,xmr,ymr l_margin_line_x.append(xml) l_margin_line_y.append(yml) r_margin_line_x.append(xmr) r_margin_line_y.append(ymr) margin_line_l.set_xdata(l_margin_line_x) margin_line_l.set_ydata(l_margin_line_y) margin_line_r.set_xdata(r_margin_line_x) margin_line_r.set_ydata(r_margin_line_y) """ f.canvas.draw() elif ax == axarr[1] and event.button == 3: # Collect data B = [] S = [] xf = [] yf = [] """ What a f*****g abortion, trying to keep the spacing of interpolated points even while moving through the individual points in the profile. This works within a meter or so, meaning that the difference between RESOLUTION and what is actually done is at most a meter. """ for i in range(1, len(line_points_x)): dx = line_points_x[i] - line_points_x[i - 1] dy = line_points_y[i] - line_points_y[i - 1] d = sqrt(dx**2 + dy**2) xhat = dx / d yhat = dy / d total_distance = 0. if i == 1: p = 0 remainder = 0 else: p = 1 while (p * RESOLUTION + (RESOLUTION - remainder)) < d: if p <= 1: xf.append(line_points_x[i - 1] + xhat * p * (RESOLUTION - remainder)) yf.append(line_points_y[i - 1] + yhat * p * (RESOLUTION - remainder)) else: xf.append(xf[-1] + xhat * RESOLUTION) yf.append(yf[-1] + yhat * RESOLUTION) p += 1 remainder = d - ((p - 2) * RESOLUTION + (RESOLUTION - remainder)) for x, y in zip(xf, yf): B.append(Binterp(x, y)) S.append(Sinterp(x, y)) # print x,y,B[-1],S[-1] B = array(B)[:, 0] S = array(S)[:, 0] # Smooth the surface #S = smooth(S,15) #B = smooth(B,15) # Plot data ff, ax = plt.subplots(1) ax.plot(B, lw=4) ax.plot(S, lw=4) plt.show() # Write data N = len(B) mesh = fc.IntervalMesh(N - 1, 0, RESOLUTION * (N - 1)) V = fc.FunctionSpace(mesh, "CG", 1) hfile = fc.HDF5File(mesh.mpi_comm(), "latest_profile.h5", "w") H = S - B S[H <= THICKLIMIT] = B[H <= THICKLIMIT] # Functions with the data as a vector and V is the functionspace Bed = fc.Function(V, name="Bed") Surface = fc.Function(V, name="Surface") Bed.vector()[:] = B Surface.vector()[:] = S hfile.write(Bed.vector(), "/bed") hfile.write(Surface.vector(), "/surface") hfile.write(mesh, "/mesh") hfile.close()
def init_V(self): ''' This function sets up various parameters for the calculation of the chemical potential profile using fenics. It is generally assumed that during the simulation of a 'sample' the following are unchanged: - dopant positions - electrode positions/number Note: only 2D support for now ''' # Turn off log messages fn.set_log_level(logging.WARNING) # Put electrode positions and values in a dict self.fn_electrodes = {} for i in range(self.P): self.fn_electrodes[f'e{i}_x'] = self.electrodes[i, 0] if(self.dim > 1): self.fn_electrodes[f'e{i}_y'] = self.electrodes[i, 1] self.fn_electrodes[f'e{i}'] = self.electrodes[i, 3] for i in range(self.static_electrodes.shape[0]): self.fn_electrodes[f'es{i}_x'] = self.static_electrodes[i, 0] if(self.dim > 1): self.fn_electrodes[f'es{i}_y'] = self.static_electrodes[i, 1] self.fn_electrodes[f'es{i}'] = self.static_electrodes[i, 3] # Define boundary expression string self.fn_expression = '' if(self.dim == 1): for i in range(self.P): self.fn_expression += (f'x[0] == e{i}_x ? e{i} : ') for i in range(self.static_electrodes.shape[0]): self.fn_expression += (f'x[0] == es{i}_x ? es{i} : ') if(self.dim == 2): surplus = self.xdim/10 # Electrode modelled as point +/- surplus #TODO: Make this not hardcoded for i in range(self.P): if(self.electrodes[i, 0] == 0 or self.electrodes[i, 0] == self.xdim): self.fn_expression += (f'x[0] == e{i}_x && ' f'x[1] >= e{i}_y - {surplus} && ' f'x[1] <= e{i}_y + {surplus} ? e{i} : ') else: self.fn_expression += (f'x[0] >= e{i}_x - {surplus} && ' f'x[0] <= e{i}_x + {surplus} && ' f'x[1] == e{i}_y ? e{i} : ') for i in range(self.static_electrodes.shape[0]): if(self.static_electrodes[i, 0] == 0 or self.static_electrodes[i, 0] == self.xdim): self.fn_expression += (f'x[0] == es{i}_x && ' f'x[1] >= es{i}_y - {surplus} && ' f'x[1] <= es{i}_y + {surplus} ? es{i} : ') else: self.fn_expression += (f'x[0] >= es{i}_x - {surplus} && ' f'x[0] <= es{i}_x + {surplus} && ' f'x[1] == es{i}_y ? es{i} : ') self.fn_expression += f'{self.mu}' # Add constant chemical potential # Define boundary expression self.fn_boundary = fn.Expression(self.fn_expression, degree = 1, **self.fn_electrodes) # Define FEM mesh (res should be small enough, otherwise solver may break) if(self.dim == 1): self.fn_mesh = fn.IntervalMesh(int(self.xdim//self.res), 0, self.xdim) if(self.dim == 2): self.fn_mesh = fn.RectangleMesh(fn.Point(0, 0), fn.Point(self.xdim, self.ydim), int(self.xdim//self.res), int(self.ydim//self.res)) # Define function space self.fn_functionspace = fn.FunctionSpace(self.fn_mesh, 'P', 1) # Define fenics boundary condition self.fn_bc = fn.DirichletBC(self.fn_functionspace, self.fn_boundary, self.fn_onboundary) # Write problem as fn_a == fn_L self.V = fn.TrialFunction(self.fn_functionspace) self.fn_v = fn.TestFunction(self.fn_functionspace) self.fn_a = fn.dot(fn.grad(self.V), fn.grad(self.fn_v)) * fn.dx self.fn_f = fn.Constant(0) self.fn_L = self.fn_f*self.fn_v*fn.dx # Solve V self.V = fn.Function(self.fn_functionspace) fn.solve(self.fn_a == self.fn_L, self.V, self.fn_bc)