def unitcube_geometry(): N = 3 mesh = UnitCubeMesh(mpi_comm_world(), N, N, N) ffun = dolfin.MeshFunction("size_t", mesh, 2) ffun.set_all(0) fixed.mark(ffun, fixed_marker) free.mark(ffun, free_marker) marker_functions = MarkerFunctions(ffun=ffun) # Fibers V_f = dolfin.VectorFunctionSpace(mesh, "CG", 1) f0 = interpolate(Expression(("1.0", "0.0", "0.0"), degree=1), V_f) s0 = interpolate(Expression(("0.0", "1.0", "0.0"), degree=1), V_f) n0 = interpolate(Expression(("0.0", "0.0", "1.0"), degree=1), V_f) microstructure = Microstructure(f0=f0, s0=s0, n0=n0) geometry = Geometry( mesh=mesh, marker_functions=marker_functions, microstructure=microstructure, ) return geometry
def _build_geo(self, gamma_sp, length, x1, x2, dim): if dim == 2: self.Gsub2 = None # Construct the actual fenics map self.gamma = Expression((ccode(gamma_sp[0]).replace( 'M_PI', 'pi'), ccode(gamma_sp[1]).replace('M_PI', 'pi')), pi=pi, length=length, degree=DEGREE, name="gamma") # Get the induced base from the mapping to the referrential geometry # G_2 = ∂X/xi^2 self.Gsub1 = Expression( (ccode(gamma_sp[0].diff(x1)).replace('M_PI', 'pi'), ccode(gamma_sp[1].diff(x1)).replace('M_PI', 'pi')), pi=pi, length=length, degree=DEGREE, name="Gsub1") if dim == 3: # Construct the actual fenics map self.gamma = Expression((ccode( gamma_sp[0]).replace('M_PI', 'pi'), ccode(gamma_sp[1]).replace( 'M_PI', 'pi'), ccode(gamma_sp[2]).replace('M_PI', 'pi')), pi=pi, length=length, degree=DEGREE, name="gamma") # Get the induced base from the mapping to the referrential geometry # G_2 = ∂X/xi^2 self.Gsub1 = Expression( (ccode(gamma_sp[0].diff(x1)).replace('M_PI', 'pi'), ccode(gamma_sp[1].diff(x1)).replace('M_PI', 'pi'), ccode(gamma_sp[2].diff(x1)).replace('M_PI', 'pi')), pi=pi, length=length, degree=DEGREE, name="Gsub1") self.Gsub2 = Expression( (ccode(gamma_sp[0].diff(x2)).replace('M_PI', 'pi'), ccode(gamma_sp[1].diff(x2)).replace('M_PI', 'pi'), ccode(gamma_sp[2].diff(x2)).replace('M_PI', 'pi')), pi=pi, length=length, degree=DEGREE, name="Gsub2")
def build_derivative(self, diff_args=None, name=None): return Expression(tuple( [ccode(i.diff(*diff_args)) for i in self.gamma_sp]), eta=self.eta, w=self.w, degree=DEGREE, name=name)
def __init__(self, w=None, eta=None, dim=None): self.w = Constant(w, name="width") self.eta = Constant(eta, name="eta") W, eta, x1, x2 = sp.symbols('w, eta, x[0], x[1]') self.dependencies = [W, eta] X, Z = ligaro(W, eta) # R = L/eta if dim == 2: self.gamma_sp = gamma_sp = [X, Z] self.Gsub2 = None if dim == 3: self.gamma_sp = gamma_sp = [X, x2, Z] # for dim==2 or dim ==3: self.gamma = Expression(tuple([ccode(i) for i in gamma_sp]), eta=self.eta, w=self.w, degree=DEGREE, name="gamma") self.Gsub1 = self.build_derivative([x1], name='Gsub1') if ADJOINT: # adjoint gamma self.gamma.dependencies = [self.w, self.eta] self.gamma.user_defined_derivatives = {} self.gamma.user_defined_derivatives[ self.w] = self.build_derivative([W], name='d_gamma_dw') self.gamma.user_defined_derivatives[ self.eta] = self.build_derivative([eta], name='d_gamma_deta') # adjoint Gsub1 self.Gsub1.dependencies = [self.w, self.eta] self.Gsub1.user_defined_derivatives = {} self.Gsub1.user_defined_derivatives[ self.w] = self.build_derivative([x1, W], name='d_Gsub1_dw') self.Gsub1.user_defined_derivatives[ self.eta] = self.build_derivative([x1, eta], name='d_Gsub1_deta') if dim == 3: self.Gsub2 = self.build_derivative([x2], name='Gsub2') if ADJOINT: self.Gsub2.dependencies = [self.w, self.eta] self.Gsub2.user_defined_derivatives = {} self.Gsub2.user_defined_derivatives[ self.w] = self.build_derivative([x2, W], name='d_Gsub2_dw') self.Gsub2.user_defined_derivatives[ self.eta] = self.build_derivative([x2, eta], name='d_Gsub2_deta')
free_marker = 2 free.mark(ffun, free_marker) # Create a cell function (but we are not using it) cfun = dolfin.MeshFunction("size_t", mesh, 3) cfun.set_all(0) # Collect the functions containing the markers marker_functions = pulse.MarkerFunctions(ffun=ffun, cfun=cfun) # Create mictrotructure V_f = dolfin.VectorFunctionSpace(mesh, "CG", 1) # Fibers f0 = interpolate(Expression(("1.0", "0.0", "0.0"), degree=1), V_f) # Sheets s0 = interpolate(Expression(("0.0", "1.0", "0.0"), degree=1), V_f) # Fiber-sheet normal n0 = interpolate(Expression(("0.0", "0.0", "1.0"), degree=1), V_f) # Collect the mictrotructure microstructure = pulse.Microstructure(f0=f0, s0=s0, n0=n0) # Create the geometry geometry = pulse.Geometry( mesh=mesh, marker_functions=marker_functions, microstructure=microstructure, )
def __init__(self, w=None, eta=None, dim=None, length=1): self.w = Constant(w, name="width") self.eta = Constant(eta, name="eta") self.t = Constant(length, name="length") W, eta, x1, x2, t = sp.symbols('w, eta, x[0], x[1], t') X, Z = ligaro(W, eta) if dim == 2: self.Gsub2 = None self.gamma_sp = gamma_sp = [X, Z] self.gamma = Expression(tuple([ccode(i) for i in gamma_sp]), eta=self.eta, w=self.w, degree=DEGREE, name="gamma") if dim == 3: self.gamma_sp = gamma_sp = [X, t * x2, Z] # fixed-end open surface volume correction # ONLY VALID FOR FIXED EDGES R = self.w / sqrt(2 * (1 - cos(self.eta))) Area = -0.5 * R**2 * (self.eta - sin(self.eta) ) # negative because upsidedown #TODO fix self.vol_correct = (Area * self.t / 3) self.gamma = Expression(tuple([ccode(i) for i in gamma_sp]), eta=self.eta, w=self.w, t=self.t, degree=DEGREE, name="gamma") self.Gsub1 = self.build_derivative([x1], name='Gsub1') if dim == 3: self.Gsub2 = self.build_derivative([x2], name='Gsub2') if ADJOINT: # adjoint gamma self.gamma.dependencies = [self.w, self.eta, self.t] self.gamma.user_defined_derivatives = {} self.gamma.user_defined_derivatives[ self.w] = self.build_derivative([W], name='d_gamma_dw') self.gamma.user_defined_derivatives[ self.eta] = self.build_derivative([eta], name='d_gamma_deta') self.gamma.user_defined_derivatives[ self.t] = self.build_derivative([t], name='d_gamma_dt') # adjoint Gsub1 self.Gsub1.dependencies = [self.w, self.eta, self.t] self.Gsub1.user_defined_derivatives = {} self.Gsub1.user_defined_derivatives[ self.w] = self.build_derivative([x1, W], name='d_Gsub1_dw') self.Gsub1.user_defined_derivatives[ self.eta] = self.build_derivative([x1, eta], name='d_Gsub1_deta') self.Gsub1.user_defined_derivatives[ self.t] = self.build_derivative([x1, t], name='d_Gsub1_dt') if dim == 3: # adjoint Gsub2 self.Gsub2.dependencies = [self.w, self.eta, self.t] self.Gsub2.user_defined_derivatives = {} self.Gsub2.user_defined_derivatives[ self.w] = self.build_derivative([x2, W], name='d_Gsub2_dw') self.Gsub2.user_defined_derivatives[ self.eta] = self.build_derivative([x2, eta], name='d_Gsub2_deta') self.Gsub2.user_defined_derivatives[ self.t] = self.build_derivative([x2, t], name='d_Gsub2_dt')
left = dolfin.CompiledSubDomain("near(x[0], side) && on_boundary", side=0) bottom = dolfin.CompiledSubDomain("near(x[2], side) && on_boundary", side=0) boundary_markers = dolfin.MeshFunction("size_t", mesh, mesh.topology().dim() - 1) boundary_markers.set_all(0) left_marker = 1 left.mark(boundary_markers, 1) bottom_marker = 2 bottom.mark(boundary_markers, 2) marker_functions = pulse.MarkerFunctions(ffun=boundary_markers) # Create mictrotructure f0 = Expression(("1.0", "0.0", "0.0"), degree=1, cell=mesh.ufl_cell()) s0 = Expression(("0.0", "1.0", "0.0"), degree=1, cell=mesh.ufl_cell()) n0 = Expression(("0.0", "0.0", "1.0"), degree=1, cell=mesh.ufl_cell()) # Collect the mictrotructure microstructure = pulse.Microstructure(f0=f0, s0=s0, n0=n0) # Create the geometry geometry = pulse.Geometry( mesh=mesh, marker_functions=marker_functions, microstructure=microstructure, ) # Create the material material_parameters = pulse.Guccione.default_parameters()
def __init__(self, w=None, L=None, dim=3): w_val = w self.length = L W, eta, L = sp.symbols('w, eta, length') x1, x2 = sp.symbols('x[0], x[1]') CC = W / L a, b, c, d, e, f = sp.symbols('a, b,c,d,e,f') eta = a + b * CC + c * CC**2 + d * CC**3 + e * sp.cos(f * CC) eta_fit = np.linspace(-6.28, 0.001, 100) x_data = np.sqrt(2 * (1 - np.cos(eta_fit)) / eta_fit**2) def test_func(x, a, b, c, d, e, f): return a + b * x + c * x**2 + d * x**3 + e * np.cos(f * x) from scipy import optimize params, params_covariance = optimize.curve_fit(test_func, x_data, eta_fit, maxfev=10000) X, Z = ligaro(W, eta) R = L / eta if dim == 2: self.Gsub2 = None gamma_sp = [None, None] gamma_sp[0] = X gamma_sp[1] = Z self.gamma = Expression((ccode(gamma_sp[0]).replace( 'M_PI', 'pi'), ccode(gamma_sp[1]).replace('M_PI', 'pi')), pi=pi, length=self.length, w=w_val, a=params[0], b=params[1], c=params[2], d=params[3], e=params[4], f=params[5], degree=DEGREE, name="gamma") # spatial derivative of above gamma (needed for PDE), similarly for \partial\gamma / \partial x2 self.Gsub1 = Expression( (ccode(gamma_sp[0].diff(x1)).replace('M_PI', 'pi'), ccode(gamma_sp[1].diff(x1)).replace('M_PI', 'pi')), pi=pi, length=self.length, w=w_val, a=params[0], b=params[1], c=params[2], d=params[3], e=params[4], f=params[5], degree=DEGREE, name="Gsub1") # Now need the derivatives of the above wrt length for dolfin-adjoint self.d_gamma = Expression( (ccode(gamma_sp[0].diff(L)).replace('M_PI', 'pi'), ccode(gamma_sp[1].diff(L)).replace('M_PI', 'pi')), pi=pi, length=self.length, w=w_val, a=params[0], b=params[1], c=params[2], d=params[3], e=params[4], f=params[5], degree=DEGREE, name="d_gamma") self.d_Gsub1 = Expression( (ccode(gamma_sp[0].diff(x1, L)).replace('M_PI', 'pi'), ccode(gamma_sp[1].diff(x1, L)).replace('M_PI', 'pi')), pi=pi, length=self.length, w=w_val, a=params[0], b=params[1], c=params[2], d=params[3], e=params[4], f=params[5], degree=DEGREE, name="d_Gsub1") # per the example, store the derivatives as dictionaries self.gamma.dependencies = [self.length] self.gamma.user_defined_derivatives = {self.length: self.d_gamma} self.Gsub1.dependencies = [self.length] self.Gsub1.user_defined_derivatives = {self.length: self.d_Gsub1} if dim == 3: gamma_sp = [None, None, None] gamma_sp[0] = X gamma_sp[1] = x2 gamma_sp[2] = Z self.gamma = Expression((ccode( gamma_sp[0]).replace('M_PI', 'pi'), ccode(gamma_sp[1]).replace( 'M_PI', 'pi'), ccode(gamma_sp[2]).replace('M_PI', 'pi')), pi=pi, length=self.length, w=w_val, a=params[0], b=params[1], c=params[2], d=params[3], e=params[4], f=params[5], degree=DEGREE, name="gamma") # spatial derivative of above gamma (needed for PDE), similarly for \partial\gamma / \partial x2 self.Gsub1 = Expression( (ccode(gamma_sp[0].diff(x1)).replace('M_PI', 'pi'), ccode(gamma_sp[1].diff(x1)).replace('M_PI', 'pi'), ccode(gamma_sp[2].diff(x1)).replace('M_PI', 'pi')), pi=pi, length=self.length, w=w_val, a=params[0], b=params[1], c=params[2], d=params[3], e=params[4], f=params[5], degree=DEGREE, name="Gsub1") self.Gsub2 = Expression( (ccode(gamma_sp[0].diff(x2)).replace('M_PI', 'pi'), ccode(gamma_sp[1].diff(x2)).replace('M_PI', 'pi'), ccode(gamma_sp[2].diff(x2)).replace('M_PI', 'pi')), pi=pi, length=self.length, w=w_val, a=params[0], b=params[1], c=params[2], d=params[3], e=params[4], f=params[5], degree=DEGREE, name="Gsub2") # Now need the derivatives of the above wrt length for dolfin-adjoint self.d_gamma = Expression( (ccode(gamma_sp[0].diff(L)).replace('M_PI', 'pi'), ccode(gamma_sp[1].diff(L)).replace('M_PI', 'pi'), ccode(gamma_sp[2].diff(L)).replace('M_PI', 'pi')), pi=pi, length=self.length, w=w_val, a=params[0], b=params[1], c=params[2], d=params[3], e=params[4], f=params[5], degree=DEGREE, name="d_gamma") self.d_Gsub1 = Expression( (ccode(gamma_sp[0].diff(x1, L)).replace('M_PI', 'pi'), ccode(gamma_sp[1].diff(x1, L)).replace('M_PI', 'pi'), ccode(gamma_sp[2].diff(x1, L)).replace('M_PI', 'pi')), pi=pi, length=self.length, w=w_val, a=params[0], b=params[1], c=params[2], d=params[3], e=params[4], f=params[5], degree=DEGREE, name="d_Gsub1") self.d_Gsub2 = Expression( (ccode(gamma_sp[0].diff(x2, L)).replace('M_PI', 'pi'), ccode(gamma_sp[1].diff(x2, L)).replace('M_PI', 'pi'), ccode(gamma_sp[2].diff(x2, L)).replace('M_PI', 'pi')), pi=pi, length=self.length, w=w_val, a=params[0], b=params[1], c=params[2], d=params[3], e=params[4], f=params[5], degree=DEGREE, name="d_Gsub2") # per the example, store the derivatives as dictionaries self.gamma.dependencies = [self.length] self.gamma.user_defined_derivatives = {self.length: self.d_gamma} self.Gsub1.dependencies = [self.length] self.Gsub1.user_defined_derivatives = {self.length: self.d_Gsub1} self.Gsub2.dependencies = [self.length] self.Gsub2.user_defined_derivatives = {self.length: self.d_Gsub2}