def setup_norot_elast(mesh, mu=1, lam=0, f_vol=None, multidim=True, reorder=False, diri=".*", order=1, fes_opts=dict(), blf_opts=dict(), lf_opts=dict()): dim = mesh.dim if multidim: V = ngs.H1(mesh, order=order, dirichlet=diri, **fes_opts, dim=mesh.dim) else: V = ngs.VectorH1(mesh, order=order, dirichlet=diri, **fes_opts) if reorder: raise Exception( "reordered does not work anymore (now ordered by elements)!!") V = ngs.comp.Reorder(V) u, v = V.TnT() sym = lambda X: 0.5 * (X + X.trans) grd = lambda X: ngs.CoefficientFunction(tuple( ngs.grad(X)[i, j] for i in range(dim) for j in range(dim)), dims=(dim, dim)) eps = lambda X: sym(grd(X)) a = ngs.BilinearForm(V, symmetric=False, **blf_opts) a += mu * ngs.InnerProduct(eps(u), eps(v)) * ngs.dx if lam != 0: div = lambda U: sum([ngs.grad(U)[i, i] for i in range(1, dim)], start=ngs.grad(U)[0, 0]) a += lam * div(u) * div(v) * ngs.dx lf = ngs.LinearForm(V) lf += f_vol * v * ngs.dx return V, a, lf
def setup_rot_elast(mesh, mu=1, lam=0, f_vol=None, multidim=True, reorder=False, diri=".*", order=1, fes_opts=dict(), blf_opts=dict(), lf_opts=dict()): dim = mesh.dim mysum = lambda x: sum(x[1:], x[0]) if dim == 2: to_skew = lambda x: ngs.CoefficientFunction( (0, -x[0], x[0], 0), dims=(2, 2)) else: # to_skew = lambda x : ngs.CoefficientFunction( ( 0 , x[2], -x[1], \ # -x[2], 0 , x[0], \ # x[1], -x[0], 0), dims = (3,3) ) to_skew = lambda x : ngs.CoefficientFunction( ( 0 , -x[2], x[1], \ x[2], 0 , -x[0], \ -x[1], x[0], 0), dims = (3,3) ) if multidim: mdim = dim + ((dim - 1) * dim) // 2 V = ngs.H1(mesh, order=order, dirichlet=diri, **fes_opts, dim=mdim) if reorder: V = ngs.comp.Reorder(V) trial, test = V.TnT() u = ngs.CoefficientFunction(tuple(trial[x] for x in range(dim))) gradu = ngs.CoefficientFunction(tuple( ngs.Grad(trial)[i, j] for i in range(dim) for j in range(dim)), dims=(dim, dim)) divu = mysum([ngs.Grad(trial)[i, i] for i in range(dim)]) w = to_skew([trial[x] for x in range(dim, mdim)]) ut = ngs.CoefficientFunction(tuple(test[x] for x in range(dim))) gradut = ngs.CoefficientFunction(tuple( ngs.Grad(test)[i, j] for i in range(dim) for j in range(dim)), dims=(dim, dim)) divut = mysum([ngs.Grad(test)[i, i] for i in range(dim)]) wt = to_skew([test[x] for x in range(dim, mdim)]) else: Vu = ngs.VectorH1(mesh, order=order, dirichlet=diri, **fes_opts) if reorder == "sep": Vu = ngs.comp.Reorder(Vu) if dim == 3: Vw = Vu else: Vw = ngs.H1(mesh, order=order, dirichlet=diri, **fes_opts) if reorder == "sep": Vw = ngs.comp.Reorder(Vw) V = ngs.FESpace([Vu, Vw]) # print("free pre RO: ", V.FreeDofs()) if reorder is True: V = ngs.comp.Reorder(V) # print("free post RO: ", V.FreeDofs()) (u, w), (ut, wt) = V.TnT() gradu = ngs.Grad(u) divu = mysum([ngs.Grad(u)[i, i] for i in range(dim)]) w = to_skew(w) gradut = ngs.Grad(ut) divut = mysum([ngs.Grad(ut)[i, i] for i in range(dim)]) wt = to_skew(wt) a = ngs.BilinearForm(V, **blf_opts) a += (mu * ngs.InnerProduct(gradu - w, gradut - wt)) * ngs.dx #a += ngs.InnerProduct(w,wt) * ngs.dx #trial, test = V.TnT() #a += 0.1 * ngs.InnerProduct(trial,test) * ngs.dx if lam != 0: a += lam * divu * divut * ngs.dx lf = ngs.LinearForm(V) lf += f_vol * ut * ngs.dx return V, a, lf
def get_DIM_gridfunctions(self, mesh: ngs.Mesh, interp_ord: int): """ Function to get all of the phase fields and masks as gridfunctions. This is either done by loading them from files or by constructing the numpy arrays and then converting those into gridfunctions. Args: mesh: The mesh for the gridfunctions. interp_ord: The interpolant order for the finite element space for the gridfunctions. """ if self.load_method == 'file': # The phase field and masks have already been created and saved as gridfunctions. fes = ngs.H1(mesh, order=interp_ord) phi_filename = self.config.get_item( ['PHASE FIELDS', 'phi_filename'], str) self.phi_gfu = create_and_load_gridfunction_from_file( phi_filename, fes) if self.multiple_bcs: # There are BC masks that must be loaded. for marker, filename in self.vertices.items(): mask_gfu = create_and_load_gridfunction_from_file( filename, fes) self.mask_gfu_dict[marker] = mask_gfu else: # One single mask that is just a grid function of ones. mask_gfu = ngs.GridFunction(fes) mask_gfu.Set(1.0) self.mask_gfu_dict['all'] = mask_gfu # Construct Grad(phi) and |Grad(phi)|. self.grad_phi_gfu = ngs.Grad(self.phi_gfu) self.mag_grad_phi_gfu = ngs.Norm(ngs.Grad(self.phi_gfu)) else: # The phase field and masks must be generated as numpy arrays and then converted into gridfunctions. # The phase field array has already been generated because it is needed to generate the mesh. # Construct the phase field, Grad(phi), and |Grad(phi)|. if self.N == self.N_mesh: # phi was generated on the simulation mesh, so just load phi into a gridfunction and compute Grad(phi) # and |Grad(phi)|. self.phi_gfu = numpy_to_NGSolve(self.mesh, interp_ord, self.phi_arr, self.scale, self.offset, self.dim) self.grad_phi_gfu = ngs.Grad(self.phi_gfu) self.mag_grad_phi_gfu = ngs.Norm(ngs.Grad(self.phi_gfu)) else: # phi was generated on a refined mesh, so load it into a refined mesh gridfunction, compute Grad(phi) # and |Grad(phi)|, then project all three into gridfunctions defined on the simulation mesh. phi_gfu_tmp = numpy_to_NGSolve(self.mesh_refined, interp_ord, self.phi_arr, self.scale, self.offset, self.dim) grad_phi_gfu_tmp = ngs.Grad(phi_gfu_tmp) mag_grad_phi_gfu_tmp = ngs.Norm(ngs.Grad(phi_gfu_tmp)) # Now project onto the coarse simulation mesh. fes = ngs.H1(mesh, order=interp_ord) vec_fes = ngs.VectorH1(mesh, order=interp_ord) self.phi_gfu = ngs.GridFunction(fes) self.grad_phi_gfu = ngs.GridFunction(vec_fes) self.mag_grad_phi_gfu = ngs.GridFunction(fes) self.phi_gfu.Set(phi_gfu_tmp) self.grad_phi_gfu.Set(grad_phi_gfu_tmp) self.mag_grad_phi_gfu.Set(mag_grad_phi_gfu_tmp) if self.multiple_bcs: # There are multiple BC masks that must be generated and loaded. for marker, mask_arr in self.mask_arr_dict.items(): mask_gfu = numpy_to_NGSolve(mesh, interp_ord, mask_arr, self.scale, self.offset, self.dim) self.mask_gfu_dict[marker] = mask_gfu else: # One single mask that is just a grid function of ones. mask_arr = np.ones(tuple([int(n + 1) for n in self.N])) mask_gfu = numpy_to_NGSolve(mesh, interp_ord, mask_arr, self.scale, self.offset, self.dim) self.mask_gfu_dict['all'] = mask_gfu # Save the gridfunctions if desired. save_to_file = self.config.get_item( ['PHASE FIELDS', 'save_to_file'], bool) if save_to_file: self.phi_gfu.Save(self.DIM_dir + '/phi.sol') self.ngmesh.Save(self.DIM_dir + '/mesh.vol') for marker, gfu in self.mask_gfu_dict.items(): # Save the BC masks inside the DIM bc_dir. gfu.Save(self.DIM_dir + '/bc_dir/{}_mask.sol'.format(marker))