def gen_rect_mesh(nx, ny, xmin, xmax, ymin, ymax, outfile, direction='right'): mesh = RectangleMesh(MPI.COMM_SELF, Point(xmin, ymin), Point(xmax, ymax), nx, ny, direction) File(MPI.COMM_SELF, outfile) << mesh
def get_geometry(domain_part): nx = 5 ny = 10 low_resolution = 5 high_resolution = 5 n_vertices = 20 if domain_part is DomainPart.LEFT: nx = nx * 3 elif domain_part is DomainPart.RIGHT: ny = ny * 2 elif domain_part is DomainPart.CIRCULAR: n_vertices = n_vertices elif domain_part is DomainPart.RECTANGLE: n_vertices = n_vertices else: raise Exception("invalid domain_part: {}".format(domain_part)) if domain_part is DomainPart.LEFT or domain_part is DomainPart.RIGHT: if domain_part is DomainPart.LEFT: p0 = Point(x_left, y_bottom) p1 = Point(x_coupling, y_top) elif domain_part is DomainPart.RIGHT: p0 = Point(x_coupling, y_bottom) p1 = Point(x_right, y_top) else: raise Exception("invalid control flow!") mesh = RectangleMesh(p0, p1, nx, ny) coupling_boundary = StraightBoundary() remaining_boundary = ExcludeStraightBoundary() elif domain_part is DomainPart.CIRCULAR or domain_part is DomainPart.RECTANGLE: p0 = Point(x_left, y_bottom) p1 = Point(x_right, y_top) whole_domain = mshr.Rectangle(p0, p1) if domain_part is DomainPart.CIRCULAR: circular_domain = mshr.Circle(midpoint, radius, n_vertices) mesh = mshr.generate_mesh(circular_domain, high_resolution, "cgal") elif domain_part is DomainPart.RECTANGLE: circular_domain = mshr.Circle(midpoint, radius, n_vertices) mesh = mshr.generate_mesh(whole_domain - circular_domain, low_resolution, "cgal") else: raise Exception("invalid control flow!") coupling_boundary = CircleBoundary() remaining_boundary = ExcludeCircleBoundary() else: raise Exception("invalid control flow!") return mesh, coupling_boundary, remaining_boundary
def reference_data(H, L, mesh_type, mesh_size, padding=0.07): g = kepler_jacobi_metric(c=H) (q0, p0, _, _, (c, a, b), _, _) = exact_kepler(H, L) if mesh_type == 'uniform': # uniform rectangular mesh containing the orbit mesh = RectangleMesh(Point(c[0] - a - padding, c[1] - b - padding), Point(c[0] + a + padding, c[1] + b + padding), mesh_size, mesh_size) else: # unstructured annular mesh containing the orbit ell_out = Ellipse(Point(c), a + padding, b + padding) ell_in = Ellipse(Point(c), a - padding, b - padding) domain = ell_out - ell_in mesh = generate_mesh(domain, mesh_size) return (q0, p0, g, mesh)
def get_geometry(domain_part): nx = ny = 9 if domain_part is DomainPart.LEFT: p0 = Point(x_left, y_bottom) p1 = Point(x_coupling, y_top) elif domain_part is DomainPart.RIGHT: p0 = Point(x_coupling, y_bottom) p1 = Point(x_right, y_top) else: raise Exception("invalid domain_part: {}".format(domain_part)) mesh = RectangleMesh(p0, p1, nx, ny, diagonal="left") coupling_boundary = StraightBoundary() remaining_boundary = ExcludeStraightBoundary() return mesh, coupling_boundary, remaining_boundary
def box_mesh(width=1.0, dim=1, nelements=8): """Make a rectangular mesh of dimension 1-3 Parameters: width=1.0: width (also length and height) of space dim=1: 1, 2, or 3, dimension of space nelements=8: division of space into elements """ if dim == 1: return IntervalMesh(nelements, 0.0, width) elif dim == 2: return RectangleMesh(Point(np.array([0.0, 0.0], dtype=float)), Point(np.array([width, width], dtype=float)), nelements, nelements) elif dim == 3: return BoxMesh(Point(np.array([0.0, 0.0, 0.0], dtype=float)), Point(np.array([width, width, width], dtype=float)), nelements, nelements, nelements) else: raise KSDGException("Only dimensions 1, 2, 3 supported.")
# Geometry and material properties dim = 2 # number of dimensions H = 1 W = 0.1 rho = 3000 E = 4000000 nu = 0.3 mu = Constant(E / (2.0 * (1.0 + nu))) lambda_ = Constant(E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu))) # create Mesh n_x_Direction = 4 n_y_Direction = 26 mesh = RectangleMesh(Point(-W / 2, 0), Point(W / 2, H), n_x_Direction, n_y_Direction) h = Constant(H / n_y_Direction) # create Function Space V = VectorFunctionSpace(mesh, 'P', 2) # BCs tol = 1E-14 # Trial and Test Functions du = TrialFunction(V) v = TestFunction(V) u_np1 = Function(V) saved_u_old = Function(V)
from cslvr import HybridModel, MomentumHybrid from fenics import Point, RectangleMesh, Expression, sqrt, pi alpha = 0.1 * pi / 180 L = 10000 p1 = Point(0.0, 0.0) p2 = Point(L, L) mesh = RectangleMesh(p1, p2, 25, 25) model = HybridModel(mesh, out_dir = './ISMIP_HOM_C_hybrid_results/', use_periodic = True) surface = Expression('- x[0] * tan(alpha)', alpha=alpha, element=model.Q.ufl_element()) bed = Expression('- x[0] * tan(alpha) - 1000.0', alpha=alpha, element=model.Q.ufl_element()) beta = Expression('1000 + 1000 * sin(2*pi*x[0]/L) * sin(2*pi*x[1]/L)', alpha=alpha, L=L, element=model.Q.ufl_element()) model.init_S(surface) model.init_B(bed) model.init_mask(1.0) # all grounded model.init_beta(beta) model.init_A(1e-16) mom = MomentumHybrid(model) mom.solve() model.save_xdmf(model.U3_s, 'U_S')
def build_mesh(): mesh = RectangleMesh(p0=Point(-0.5, -0.5), p1=Point(0.5, 0.5), nx=nx, ny=nx) return mesh
# Numerical properties tol = 1E-14 # Beam material properties rho = 1000 # density E = 5600000.0 # Young's modulus nu = 0.4 # Poisson's ratio lambda_ = Constant(E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu))) # first Lame constant mu = Constant(E / (2.0 * (1.0 + nu))) # second Lame constant # create Mesh n_x_Direction = 20 # DoFs in x direction n_y_Direction = 4 # DoFs in y direction mesh = RectangleMesh(Point(x_left, y_bottom), Point(x_right, y_top), n_x_Direction, n_y_Direction) # create Function Space V = VectorFunctionSpace(mesh, 'P', 2) # Trial and Test Functions du = TrialFunction(V) v = TestFunction(V) # displacement fields u_np1 = Function(V) saved_u_old = Function(V) # function known from previous timestep u_n = Function(V) v_n = Function(V)
from fenics import File if __name__ == '__main__': fenics.set_log_level(30) # only display warnings or errors # here we solve a heat diffusion equation over time: # we use a finite difference scheme in time (backward Euler) and a variational approach in space # namely we iterate over (small) timesteps, each time solving a Poisson equation via finite elements T = 2.0 # final time num_steps = 50 # number of time steps dt = T / num_steps # time step size # Create mesh and define function space nx = ny = 30 mesh = RectangleMesh(Point(-2, -2), Point(2, 2), nx, ny) V = FunctionSpace(mesh, 'P', 1) # Define boundary condition def boundary(x, on_boundary): return on_boundary bc = DirichletBC(V, Constant(0), boundary) # null Dirichlet conditions # Define initial value u_0 = Expression('exp(-a*pow(x[0], 2) - a*pow(x[1], 2))', degree=2, a=5) # the initial condition here is a "gaussian hill" of parameter alpha centered in the origin u_n = interpolate(u_0, V) # since we will be using iteratively the solution from the previous time step to compute the one # at the current time step, we need to convert the initial datum's expression to a Function object: # there are two ways to do this: either via the project() method or the interpolate() method;
def __init__(self, direc, files, flip=False, mesh=None, gen_space=True, zero_edge=False, bool_data=False, req_dg=False): """ The following data are used to initialize the class : direc : Set the directory containing the input files. files : Tuple of file names. All files are scanned for rows or columns of nans. Assume all files have the same extents. flip : flip the data over the x-axis? mesh : FEniCS mesh if there is one already created. zero_edge : Make edges of domain -0.002? bool_data : Convert data to boolean? req_dg : Some field may require DG space? Based on thickness extents, create a rectangular mesh object. Also define the function space as continious galerkin, order 1. """ self.directory = direc self.data = {} # dictionary of converted matlab data self.rem_nans = False self.chg_proj = False # change to other projection flag first = True # initialize domain by first file's extents if direc == None and type(files) == dict: self.name = files.pop('dataset') elif direc != None: self.name = direc print "::: creating %s DataInput object :::" % self.name # process the data files : for fn in files: if direc == None and type(files) == dict: d_dict = files[fn] elif direc != None: d_dict = loadmat(direc + fn) d_dict['projection'] = d_dict['projection'][0] d_dict['standard lat'] = d_dict['standard lat'][0] d_dict['standard lon'] = d_dict['standard lon'][0] d_dict['lat true scale'] = d_dict['lat true scale'][0] d = d_dict["map_data"] # initialize extents : if first: self.ny,self.nx = shape(d_dict['map_data']) self.x_min = float(d_dict['map_western_edge']) self.x_max = float(d_dict['map_eastern_edge']) self.y_min = float(d_dict['map_southern_edge']) self.y_max = float(d_dict['map_northern_edge']) self.proj = str(d_dict['projection']) self.lat_0 = str(d_dict['standard lat']) self.lon_0 = str(d_dict['standard lon']) self.lat_ts = str(d_dict['lat true scale']) self.x = linspace(self.x_min, self.x_max, self.nx) self.y = linspace(self.y_min, self.y_max, self.ny) self.good_x = array(ones(len(self.x)), dtype=bool) # no NaNs self.good_y = array(ones(len(self.y)), dtype=bool) # no NaNs first = False # identify, but not remove the NaNs : self.identify_nans(d, fn) # make edges all zero for interpolation of interior regions : if zero_edge: d[:,0] = d[:,-1] = d[0,:] = d[-1,:] = -0.002 d[:,1] = d[:,-2] = d[1,:] = d[-2,:] = -0.002 # convert to boolean : if bool_data: d[d > 0] = 1 # reflect over the x-axis : if flip: d = d[::-1, :] # add to the dictionary of arrays : self.data[fn.split('.')[0]] = d # remove un-needed rows/cols from data: if self.rem_nans: self.remove_nans() if gen_space: # define a FEniCS Rectangle over the domain : if mesh == None: self.mesh = RectangleMesh(self.x_min, self.y_min, self.x_max, self.y_max, self.nx, self.ny) else: self.mesh = mesh # define the function space of the problem : self.func_space = FunctionSpace(self.mesh, "CG", 1) # if DG space is needed : if req_dg: self.func_space_dg = FunctionSpace(self.mesh, "DG", 1) # create projection : proj = " +proj=" + self.proj \ + " +lat_0=" + self.lat_0 \ + " +lat_ts=" + self.lat_ts \ + " +lon_0=" + self.lon_0 \ + " +k=1 +x_0=0 +y_0=0 +no_defs +a=6378137 +rf=298.257223563" \ + " +towgs84=0.000,0.000,0.000 +to_meter=1" self.p = Proj(proj)
def __init__(self, mf_obj, flip=False, mesh=None, gen_space=True, zero_edge=False, bool_data=False, req_dg=False): """ The following data are used to initialize the class : mf_obj : mesh factory dictionary. flip : flip the data over the x-axis? mesh : FEniCS mesh if there is one already created. zero_edge : Make edges of domain -0.002? bool_data : Convert data to boolean? req_dg : Some field may require DG space? Based on thickness extents, create a rectangular mesh object. Also define the function space as continious galerkin, order 1. """ self.data = {} # dictionary of converted matlab data self.rem_nans = False # may change depending on 'identify_nans' call self.chg_proj = False # change to other projection flag self.color = 'light_green' mf_obj = mf_obj.copy() self.name = mf_obj.pop('dataset') self.cont = mf_obj.pop('continent') self.proj = mf_obj.pop('pyproj_Proj') # initialize extents : self.ny = mf_obj.pop('ny') self.nx = mf_obj.pop('nx') self.x_min = float(mf_obj.pop('map_western_edge')) self.x_max = float(mf_obj.pop('map_eastern_edge')) self.y_min = float(mf_obj.pop('map_southern_edge')) self.y_max = float(mf_obj.pop('map_northern_edge')) self.x = linspace(self.x_min, self.x_max, self.nx) self.y = linspace(self.y_min, self.y_max, self.ny) self.good_x = array(ones(len(self.x)), dtype=bool) # no NaNs self.good_y = array(ones(len(self.y)), dtype=bool) # no NaNs s = "::: creating %s DataInput object :::" % self.name print_text(s, self.color) # process the data mf_obj : for fn in mf_obj: # raw data matrix with key fn : d = mf_obj[fn] # identify, but not remove the NaNs : self.identify_nans(d, fn) # make edges all zero for interpolation of interior regions : if zero_edge: d[:,0] = d[:,-1] = d[0,:] = d[-1,:] = -0.002 d[:,1] = d[:,-2] = d[1,:] = d[-2,:] = -0.002 # convert to boolean : if bool_data: d[d > 0] = 1 # reflect over the x-axis : if flip: d = d[::-1, :] # add to the dictionary of arrays : self.data[fn.split('.')[0]] = d # remove un-needed rows/cols from data: if self.rem_nans: self.remove_nans() if gen_space: # define a FEniCS Rectangle over the domain : if mesh == None: self.mesh = RectangleMesh(self.x_min, self.y_min, self.x_max, self.y_max, self.nx, self.ny) else: self.mesh = mesh # define the function space of the problem : self.func_space = FunctionSpace(self.mesh, "CG", 1) # if DG space is needed : if req_dg: self.func_space_dg = FunctionSpace(self.mesh, "DG", 1) self.mesh.init(1,2) self.dim = self.mesh.ufl_cell().topological_dimension() if self.dim == 3: self.num_facets = self.mesh.size_global(2) self.num_cells = self.mesh.size_global(3) self.dof = self.mesh.size_global(0) elif self.dim == 2: self.num_facets = self.mesh.size_global(1) self.num_cells = self.mesh.size_global(2) self.dof = self.mesh.size_global(0) s = " - using %iD mesh with %i cells, %i facets, %i vertices - " \ % (self.dim, self.num_cells, self.num_facets, self.dof) print_text(s, self.color) else: s = " - not using a mesh - " print_text(s, self.color)
class DataInput(object): """ This object brokers the relation between the driver file and a number of data sets. It's function is to: 1) Read the data. Presently it is assumed that all input is Matlab V5. 2) Filter or process the data. Presently the only filter is to remove rows or columns in key data sets that are entirely not a number. 3) Project the data onto a finite element mesh that is generated based on the extents of the input data set. """ def __init__(self, mf_obj, flip=False, mesh=None, gen_space=True, zero_edge=False, bool_data=False, req_dg=False): """ The following data are used to initialize the class : mf_obj : mesh factory dictionary. flip : flip the data over the x-axis? mesh : FEniCS mesh if there is one already created. zero_edge : Make edges of domain -0.002? bool_data : Convert data to boolean? req_dg : Some field may require DG space? Based on thickness extents, create a rectangular mesh object. Also define the function space as continious galerkin, order 1. """ self.data = {} # dictionary of converted matlab data self.rem_nans = False # may change depending on 'identify_nans' call self.chg_proj = False # change to other projection flag self.color = 'light_green' mf_obj = mf_obj.copy() self.name = mf_obj.pop('dataset') self.cont = mf_obj.pop('continent') self.proj = mf_obj.pop('pyproj_Proj') # initialize extents : self.ny = mf_obj.pop('ny') self.nx = mf_obj.pop('nx') self.x_min = float(mf_obj.pop('map_western_edge')) self.x_max = float(mf_obj.pop('map_eastern_edge')) self.y_min = float(mf_obj.pop('map_southern_edge')) self.y_max = float(mf_obj.pop('map_northern_edge')) self.x = linspace(self.x_min, self.x_max, self.nx) self.y = linspace(self.y_min, self.y_max, self.ny) self.good_x = array(ones(len(self.x)), dtype=bool) # no NaNs self.good_y = array(ones(len(self.y)), dtype=bool) # no NaNs s = "::: creating %s DataInput object :::" % self.name print_text(s, self.color) # process the data mf_obj : for fn in mf_obj: # raw data matrix with key fn : d = mf_obj[fn] # identify, but not remove the NaNs : self.identify_nans(d, fn) # make edges all zero for interpolation of interior regions : if zero_edge: d[:,0] = d[:,-1] = d[0,:] = d[-1,:] = -0.002 d[:,1] = d[:,-2] = d[1,:] = d[-2,:] = -0.002 # convert to boolean : if bool_data: d[d > 0] = 1 # reflect over the x-axis : if flip: d = d[::-1, :] # add to the dictionary of arrays : self.data[fn.split('.')[0]] = d # remove un-needed rows/cols from data: if self.rem_nans: self.remove_nans() if gen_space: # define a FEniCS Rectangle over the domain : if mesh == None: self.mesh = RectangleMesh(self.x_min, self.y_min, self.x_max, self.y_max, self.nx, self.ny) else: self.mesh = mesh # define the function space of the problem : self.func_space = FunctionSpace(self.mesh, "CG", 1) # if DG space is needed : if req_dg: self.func_space_dg = FunctionSpace(self.mesh, "DG", 1) self.mesh.init(1,2) self.dim = self.mesh.ufl_cell().topological_dimension() if self.dim == 3: self.num_facets = self.mesh.size_global(2) self.num_cells = self.mesh.size_global(3) self.dof = self.mesh.size_global(0) elif self.dim == 2: self.num_facets = self.mesh.size_global(1) self.num_cells = self.mesh.size_global(2) self.dof = self.mesh.size_global(0) s = " - using %iD mesh with %i cells, %i facets, %i vertices - " \ % (self.dim, self.num_cells, self.num_facets, self.dof) print_text(s, self.color) else: s = " - not using a mesh - " print_text(s, self.color) def change_projection(self, di): """ change the projection of this data to that of the <di> DataInput object's projection. The works only if the object was created with the parameter create_proj = True. """ if type(di) == type(self): proj = di.proj name = di.name elif type(di) == dict: name = di['dataset'] proj = di['pyproj_Proj'] s = "::: changing '%s' DataInput object projection to that of '%s' :::" \ % (self.name, name) print_text(s, self.color) self.chg_proj = True self.new_p = proj def get_xy(self,lon,lat): """ Returns the (x,y) flat map coordinates corresponding to a given (lon,lat) coordinate pair using the DataInput object's current projection. """ return self.proj(lon,lat) def interpolate_to_di(self, do, fn, fo): """ interpolate the field with name <fn> from this dataInput object to the grid used by the other dataInput object <do>. The field is saved to <do>.data[<fo>]. """ s = "::: interpolating %s's '%s' field to %s's grid with key '%s' :::" print_text(s % (self.name, fn, do.name, fo) , self.color) interp = interp2d(self.x, self.y, self.data[fn]) fo_v = interp(do.x, do.y) do.data[fo] = fo_v def transform_xy(self, di): """ Transforms the coordinates from DataInput object <di> to this object's coordinates. Returns tuple of arrays (x,y). """ # FIXME : need a fast way to convert all the x, y. Currently broken s = "::: transforming coordinates from %s to %s :::" % (di.name, self.name) print_text(s, self.color) xn, yn = transform(di.proj, self.proj, di.x, di.y) return (xn, yn) def rescale_field(self, fo, fn, umin, umax, inverse=False): """ Rescale the data field with key <fo> with lower and upper bound <umin>, <umax>, creating a new data field with key <fn>. If <inverse> == True, scale the data to the inverse of the data <fo>, i.e., the smallest values become <umax>, and the largest become <umin>. This is useful, for example, when refining a mesh in areas where a velocity field is high. """ if inverse: inv_txt = 'inversely' elif not inverse: inv_txt = '' s = "::: rescaling data field '%s' %s with lower and upper " + \ "bound (%g, %g) to field '%s' :::" print_text(s % (fo, inv_txt, umin, umax, fn), self.color) U = self.data[fo] if not inverse: amin = ( umin/(1.0 + U.max()) - umax/(1.0 + U.min()) ) / (umax - umin) amax = umin / ( amin + 1.0/(1.0 + U.min()) ) elif inverse: amin = ( umin/(1.0 + U.min()) - umax/(1.0 + U.max()) ) / (umax - umin) amax = umin / ( amin + 1.0/(1.0 + U.max()) ) self.data[fn] = (amin + 1.0/(1.0 + U)) * amax def integrate_field(self, fn_spec, specific, fn_main, r=20, val=0.0): """ Assimilate a field with filename <fn_spec> from DataInput object <specific> into this DataInput's field with filename <fn_main>. The parameter <val> should be set to the specific dataset's value for undefined regions, default is 0.0. <r> is a parameter used to eliminate border artifacts from interpolation; increase this value to eliminate edge noise. """ s = "::: integrating %s field from %s :::" % (fn_spec, specific.name) print_text(s, self.color) # get the dofmap to map from mesh vertex indices to function indicies : df = self.func_space.dofmap() dfmap = df.vertex_to_dof_map(self.mesh) unew = self.get_projection(fn_main) # existing dataset projection uocom = unew.compute_vertex_values() # mesh indexed main vertex values uspec = specific.get_projection(fn_spec) # specific dataset projection uscom = uspec.compute_vertex_values() # mesh indexed spec vertex values d = float64(specific.data[fn_spec]) # original matlab spec dataset # get arrays of x-values for specific domain xs = specific.x ys = specific.y nx = specific.nx ny = specific.ny for v in vertices(self.mesh): # mesh vertex x,y coordinate : i = v.index() p = v.point() x = p.x() y = p.y() # indexes of closest datapoint to specific dataset's x and y domains : idx = abs(xs - x).argmin() idy = abs(ys - y).argmin() # data value for closest value and square around the value in question : dv = d[idy, idx] db = d[max(0,idy-r) : min(ny, idy+r), max(0, idx-r) : min(nx, idx+r)] # if the vertex is in the domain of the specific dataset, and the value # of the dataset at this point is not abov <val>, set the array value # of the main file to this new specific region's value. if dv > val: #print "found:", x, y, idx, idy, v.index() # if the values is not near an edge, make the value equal to the # nearest specific region's dataset value, otherwise, use the # specific region's projected value : if all(db > val): uocom[i] = uscom[i] else : uocom[i] = dv # set the values of the projected original dataset equal to the assimilated # dataset : unew.vector().set_local(uocom[dfmap]) return unew def identify_nans(self, data, fn): """ private method to identify rows and columns of all nans from grids. This happens when the data from multiple GIS databases don't quite align on whatever the desired grid is. """ good_x = ~all(isnan(data), axis=0) & self.good_x # good cols good_y = ~all(isnan(data), axis=1) & self.good_y # good rows if any(good_x != self.good_x): total_nan_x = sum(good_x == False) self.rem_nans = True s = "Warning: %d row(s) of \"%s\" are entirely NaN." % (total_nan_x, fn) print_text(s, self.color) if any(good_y != self.good_y): total_nan_y = sum(good_y == False) self.rem_nans = True s = "Warning: %d col(s) of \"%s\" are entirely NaN." % (total_nan_y, fn) print_text(s, self.color) self.good_x = good_x self.good_y = good_y def remove_nans(self): """ remove extra rows/cols from data where NaNs were identified and set the extents to those of the good x and y values. """ s = "::: removing NaNs from %s :::" % self.name print_text(s, self.color) self.x = self.x[self.good_x] self.y = self.y[self.good_y] self.x_min = self.x.min() self.x_max = self.x.max() self.y_min = self.y.min() self.y_max = self.y.max() self.nx = len(self.x) self.ny = len(self.y) for i in self.data.keys(): self.data[i] = self.data[i][self.good_y, : ] self.data[i] = self.data[i][:, self.good_x] def set_data_min(self, fn, boundary, val): """ set the minimum value of a data array with filename <fn> below <boundary> to value <val>. """ s = "::: setting any value of %s's %s field below %.3e to %.3e :::" \ % (self.name, fn, boundary, val) print_text(s, self.color) d = self.data[fn] d[d <= boundary] = val self.data[fn] = d def set_data_max(self, fn, boundary, val): """ set the maximum value of a data array with filename <fn> above <boundary> to value <val>. """ s = "::: setting any value of %s's %s field above %.3e to %.3e :::" \ % (self.name, fn, boundary, val) print_text(s, self.color) d = self.data[fn] d[d >= boundary] = val self.data[fn] = d def set_data_val(self, fn, old_val, new_val): """ set all values of the matrix with filename <fn> equal to <old_val> to <new_val>. """ s = "::: setting all values of %s's %s field equal to %.3e to %.3e :::" \ % (self.name, fn, old_val, new_val) print_text(s, self.color) d = self.data[fn] d[d == old_val] = new_val self.data[fn] = d def get_interpolation(self, fn, near=False, bool_data=False, order=1): """ Return a projection of data with field name <fn> on the functionspace. If multiple instances of the DataInput class are present, both initialized with identical meshes, the projections returned by this function may be used by the same mathematical problem. If <bool_data> is True, convert all values > 0 to 1. <order> sets the order of the interpolation, default linear (1). """ if near: t = 'nearest-neighbor' else: t = 'spline' s = "::: getting %s %s interpolation from %s :::" % (fn, t, self.name) print_text(s, self.color) interp = self.get_expression(fn, kx=order, ky=order, bool_data=bool_data, near=near) return interpolate(interp, self.func_space, annotate=False) def get_expression(self, fn, order=1, bool_data=False, near=False): """ Creates a spline-interpolation expression for data <fn>. Optional argument <order> determine order of approximation in x and y directions (default linear). If <bool_data> is True, convert to boolean, if <near> is True, use nearest-neighbor interpolation. """ if near: t = 'nearest-neighbor' else: t = '%i-order spline' % order s = "::: getting %s %s expression from %s :::" % (fn, t, self.name) print_text(s, self.color) data = self.data[fn] if bool_data: data[data > 0] = 1 if self.chg_proj: new_proj = self.new_p old_proj = self.proj if not near : spline = RectBivariateSpline(self.x, self.y, data.T, kx=order, ky=order) xs = self.x ys = self.y chg_proj = self.chg_proj class newExpression(Expression): def eval(self, values, x): if chg_proj: xn, yn = transform(new_proj, old_proj, x[0], x[1]) else: xn, yn = x[0], x[1] if not near: values[0] = spline(xn, yn) else: idx = abs(xs - xn).argmin() idy = abs(ys - yn).argmin() values[0] = data[idy, idx] return newExpression(element = self.func_space.ufl_element()) def get_nearest(self, fn): """ returns a dolfin Function object with values given by interpolated nearest-neighbor data <fn>. """ #FIXME: get to work with a change of projection. # get the dofmap to map from mesh vertex indices to function indicies : df = self.func_space.dofmap() dfmap = df.vertex_to_dof_map(self.mesh) unew = Function(self.func_space) # existing dataset projection uocom = unew.vector().array() # mesh indexed main vertex values d = float64(self.data[fn]) # original matlab spec dataset # get arrays of x-values for specific domain xs = self.x ys = self.y for v in vertices(self.mesh): # mesh vertex x,y coordinate : i = v.index() p = v.point() x = p.x() y = p.y() # indexes of closest datapoint to specific dataset's x and y domains : idx = abs(xs - x).argmin() idy = abs(ys - y).argmin() # data value for closest value : dv = d[idy, idx] if dv > 0: dv = 1.0 uocom[i] = dv # set the values of the empty function's vertices to the data values : unew.vector().set_local(uocom[dfmap]) return unew
def get_uniform_mesh(self, temporal_nodes, spatial_nodes): """Generate uniform mesh of the spacetime.""" return RectangleMesh(Point(self.t0, self.x0), Point(self.t1, self.x1), temporal_nodes, spatial_nodes)
# Create mesh and define function space nx = 100 ny = 25 nz = 1 fenics_dt = 0.01 # time step size dt_out = 0.2 # interval for writing VTK files y_top = 0 y_bottom = y_top - .25 x_left = 0 x_right = x_left + 1 p0 = Point(x_left, y_bottom, 0) p1 = Point(x_right, y_top, 1) mesh = RectangleMesh(p0, p1, nx, ny) V = FunctionSpace(mesh, 'P', 1) V_g = VectorFunctionSpace(mesh, 'P', 1) alpha = 1 # m^2/s, https://en.wikipedia.org/wiki/Thermal_diffusivity k = 100 # kg * m / s^3 / K, https://en.wikipedia.org/wiki/Thermal_conductivity # Define boundary condition u_D = Constant('310') u_D_function = interpolate(u_D, V) # We will only exchange flux in y direction on coupling interface. No initialization necessary. V_flux_y = V_g.sub(1) coupling_boundary = TopBoundary() bottom_boundary = BottomBoundary()
# Geometry and material properties dim = 2 # number of dimensions H = 1 W = 0.1 rho = 3000 E = 400000.0 nu = 0.3 mu = Constant(E / (2.0 * (1.0 + nu))) lambda_ = Constant(E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu))) # create Mesh n_x_Direction = 5 n_y_Direction = 50 mesh = RectangleMesh(Point(-W / 2, 0), Point(W / 2, H), n_x_Direction, n_y_Direction) h = Constant(H / n_y_Direction) # create Function Space V = VectorFunctionSpace(mesh, 'P', 2) # BCs tol = 1E-14 # Trial and Test Functions du = TrialFunction(V) v = TestFunction(V) u_np1 = Function(V) saved_u_old = Function(V)
bilinear_form_solid_adjoint, functional_solid_adjoint, ) from relaxation import relaxation from shooting import shooting from compute_residuals import compute_residuals from refine import refine parameters["allow_extrapolation"] = True param = Parameters() # Create meshes mesh_f = RectangleMesh( Point(0.0, 0.0), Point(4.0, 1.0), param.NUMBER_ELEMENTS_HORIZONTAL, param.NUMBER_ELEMENTS_VERTICAL, diagonal="right", ) mesh_s = RectangleMesh( Point(0.0, -1.0), Point(4.0, 0.0), param.NUMBER_ELEMENTS_HORIZONTAL, param.NUMBER_ELEMENTS_VERTICAL, diagonal="left", ) boundary_mesh = BoundaryMesh(mesh_f, "exterior") inner_boundary = Inner_boundary() mesh_i = SubMesh(boundary_mesh, inner_boundary) # Create function spaces
alpha = 3 # parameter alpha beta = 1.3 # parameter beta gamma = args.gamma # parameter gamma, dependence of heat flux on time y_bottom, y_top = 0, 1 x_left, x_right = 0, 2 x_coupling = 1.5 # x coordinate of coupling interface if domain_part is DomainPart.LEFT: p0 = Point(x_left, y_bottom) p1 = Point(x_coupling, y_top) elif domain_part is DomainPart.RIGHT: p0 = Point(x_coupling, y_bottom) p1 = Point(x_right, y_top) mesh = RectangleMesh(p0, p1, nx, ny) V = FunctionSpace(mesh, 'P', 2) # Define boundary condition u_D = Expression( '1 + gamma*t*x[0]*x[0] + (1-gamma)*x[0]*x[0] + alpha*x[1]*x[1] + beta*t', degree=2, alpha=alpha, beta=beta, gamma=gamma, t=0) u_D_function = interpolate(u_D, V) # Define flux in x direction on coupling interface (grad(u_D) in normal direction) f_N = Expression('2 * gamma*t*x[0] + 2 * (1-gamma)*x[0] ', degree=1, gamma=gamma,
def build_mesh(): mesh = RectangleMesh(p0=Point(-2,-2), p1=Point(2,2), nx=nx, ny=nx) return mesh