def test_Probes_vectorfunctionspace_3D(VF3, dirpath): u0 = interpolate(Expression(('x[0]', 'x[1]', 'x[2]'), degree=1), VF3) x = array([[0.5, 0.5, 0.5], [0.4, 0.4, 0.4], [0.3, 0.3, 0.3]]) p = Probes(x.flatten(), VF3) # Probe twice p(u0) p(u0) # Check both snapshots p0 = p.array(N=0) if MPI.rank(MPI.comm_world) == 0: assert round(p0[0, 0] - 0.5, 7) == 0 assert round(p0[1, 1] - 0.4, 7) == 0 assert round(p0[2, 2] - 0.3, 7) == 0 p0 = p.array(N=1) if MPI.rank(MPI.comm_world) == 0: assert round(p0[0, 0] - 0.5, 7) == 0 assert round(p0[1, 1] - 0.4, 7) == 0 assert round(p0[2, 2] - 0.3, 7) == 0 p0 = p.array(filename=dirpath+'dumpvector3D') if MPI.rank(MPI.comm_world) == 0: assert round(p0[0, 0, 0] - 0.5, 7) == 0 assert round(p0[1, 1, 0] - 0.4, 7) == 0 assert round(p0[2, 1, 0] - 0.3, 7) == 0 p1 = load(dirpath+'dumpvector3D_all.npy') assert round(p1[0, 0, 0] - 0.5, 7) == 0 assert round(p1[1, 1, 0] - 0.4, 7) == 0 assert round(p1[2, 1, 1] - 0.3, 7) == 0
def test_Probes_vectorfunctionspace_2D(VF2, dirpath): u0 = interpolate(Expression(('x[0]', 'x[1]')), VF2) x = array([[0.5, 0.5], [0.4, 0.4], [0.3, 0.3]]) p = Probes(x.flatten(), VF2) # Probe twice p(u0) p(u0) # Check both snapshots p0 = p.array(N=0) if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0, 0] - 0.5, 7) == 0 assert round(p0[1, 1] - 0.4, 7) == 0 assert round(p0[2, 1] - 0.3, 7) == 0 p0 = p.array(N=1) if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0, 0] - 0.5, 7) == 0 assert round(p0[1, 0] - 0.4, 7) == 0 assert round(p0[2, 1] - 0.3, 7) == 0 p0 = p.array(filename=dirpath+'dumpvector2D') if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0, 0, 0] - 0.5, 7) == 0 assert round(p0[1, 1, 1] - 0.4, 7) == 0 assert round(p0[2, 0, 1] - 0.3, 7) == 0 f = open(dirpath+'dumpvector2D_all.probes', 'r') p1 = load(f) assert round(p1[0, 0, 0] - 0.5, 7) == 0 assert round(p1[1, 1, 0] - 0.4, 7) == 0 assert round(p1[2, 1, 1] - 0.3, 7) == 0
def test_Probes_vectorfunctionspace_2D(): mesh = UnitSquareMesh(4, 4) V = VectorFunctionSpace(mesh, 'CG', 1) u0 = interpolate(Expression(('x[0]', 'x[1]')), V) x = array([[0.5, 0.5], [0.4, 0.4], [0.3, 0.3]]) p = Probes(x.flatten(), V) # Probe twice p(u0) p(u0) # Check both snapshots p0 = p.array(N=0) if MPI.rank(mpi_comm_world()) == 0: nose.tools.assert_almost_equal(p0[0, 0], 0.5) nose.tools.assert_almost_equal(p0[1, 1], 0.4) nose.tools.assert_almost_equal(p0[2, 1], 0.3) p0 = p.array(N=1) if MPI.rank(mpi_comm_world()) == 0: nose.tools.assert_almost_equal(p0[0, 0], 0.5) nose.tools.assert_almost_equal(p0[1, 0], 0.4) nose.tools.assert_almost_equal(p0[2, 1], 0.3) p0 = p.array(filename='dumpvector2D') if MPI.rank(mpi_comm_world()) == 0: nose.tools.assert_almost_equal(p0[0, 0, 0], 0.5) nose.tools.assert_almost_equal(p0[1, 1, 1], 0.4) nose.tools.assert_almost_equal(p0[2, 0, 1], 0.3) f = open('dumpvector2D_all.probes', 'r') p1 = load(f) nose.tools.assert_almost_equal(p1[0, 0, 0], 0.5) nose.tools.assert_almost_equal(p1[1, 1, 0], 0.4) nose.tools.assert_almost_equal(p1[2, 1, 1], 0.3)
def test_pointsource_matrix_second_constructor(mesh, point): """Tests point source when given different constructor PointSource(V1, V2, point, mag) with a matrix and when placed at a node for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. Currently only implemented if V1=V2. """ V1 = FunctionSpace(mesh, "CG", 1) V2 = FunctionSpace(mesh, "CG", 1) rank = MPI.rank(mesh.mpi_comm()) u, v = TrialFunction(V1), TestFunction(V2) w = Function(V1) A = assemble(Constant(0.0)*u*v*dx) if rank == 0: ps = PointSource(V1, V2, point, 10.0) else: ps = PointSource(V1, V2, []) ps.apply(A) # Checks array sums to correct value a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array())) assert round(a_sum - 10.0) == 0 # Checks point source is added to correct part of the array A.get_diagonal(w.vector()) v2d = vertex_to_dof_map(V1) for v in vertices(mesh): if near(v.midpoint().distance(point), 0.0): ind = v2d[v.index()] if ind < len(A.array()): assert np.round(w.vector()[ind] - 10.0) == 0
def test_pointsource_mixed_space(mesh, point): """Tests point source when given constructor PointSource(V, point, mag) with a vector for a mixed function space that isn't placed at a node for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. """ rank = MPI.rank(mesh.mpi_comm()) ele1 = FiniteElement("CG", mesh.ufl_cell(), 1) ele2 = FiniteElement("DG", mesh.ufl_cell(), 2) ele3 = VectorElement("CG", mesh.ufl_cell(), 2) V = FunctionSpace(mesh, MixedElement([ele1, ele2, ele3])) value_dimension = V.element().value_dimension(0) v = TestFunction(V) b = assemble(dot(Constant([0.0]*value_dimension), v)*dx) if rank == 0: ps = PointSource(V, point, 10.0) else: ps = PointSource(V, []) ps.apply(b) # Checks array sums to correct value b_sum = b.sum() assert round(b_sum - 10.0*value_dimension) == 0
def test_multi_ps_matrix(mesh): """Tests point source PointSource(V, source) for mulitple point sources applied to a matrix for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. """ c_ids = [0, 1, 2] rank = MPI.rank(mesh.mpi_comm()) V = VectorFunctionSpace(mesh, "CG", 1, dim=2) u, v = TrialFunction(V), TestFunction(V) A = assemble(Constant(0.0)*dot(u, v)*dx) source = [] if rank == 0: for c_id in c_ids: cell = Cell(mesh, c_id) point = cell.midpoint() source.append((point, 10.0)) ps = PointSource(V, source) ps.apply(A) # Checks b sums to correct value a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array())) assert round(a_sum - 2*len(c_ids)*10) == 0
def __init__(self, Ys, fs, init_t = 0.0, init_dt = 1.0, dt_max = 2.0, tol = 1e-3, verbose = False): # Fenics functions for each of the unknowns self.Ys = Ys # The number of unknowns self.num_unknowns = len(self.Ys) # Slope functions corresponding to each unknown self.fs = fs # Current time self.t = init_t # Initial time step self.dt = init_dt # Maximum time step self.dt_max = dt_max # Tolerance self.tol = tol # List of lists. Each sublist stores the slope functions evaluated at the # last 5 solutions for the ith unknown self.f_ns = [[] for i in range(self.num_unknowns)] # List of solution vectors at last time step self.prev_ys = None # Flag for first step self.first = True # Output stuff? self.verbose = verbose # Store the last five solution times self.ts = [] # An object for computing integrals of basis functions for Lagrange # polynomials. This is used to determine the coefficients for the AB # and AM methods given the last five solution times self.l_int = LagrangeInt() # Process rank self.MPI_rank = MPI.rank(mpi_comm_world())
def test_pointsource_vector_fs(mesh, point): """Tests point source when given constructor PointSource(V, point, mag) with a vector for a vector function space that isn't placed at a node for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. """ rank = MPI.rank(mesh.mpi_comm()) V = VectorFunctionSpace(mesh, "CG", 1) v = TestFunction(V) b = assemble(dot(Constant([0.0]*mesh.geometry().dim()), v)*dx) if rank == 0: ps = PointSource(V, point, 10.0) else: ps = PointSource(V, []) ps.apply(b) # Checks array sums to correct value b_sum = b.sum() assert round(b_sum - 10.0*V.num_sub_spaces()) == 0 # Checks point source is added to correct part of the array v2d = vertex_to_dof_map(V) for v in vertices(mesh): if near(v.midpoint().distance(point), 0.0): for spc_idx in range(V.num_sub_spaces()): ind = v2d[v.index()*V.num_sub_spaces() + spc_idx] if ind < len(b.get_local()): assert np.round(b.get_local()[ind] - 10.0) == 0
def save_tstep_solution_h5(tstep, q_, u_, newfolder, tstepfiles, constrained_domain, output_timeseries_as_vector, u_components, AssignedVectorFunction, scalar_components, NS_parameters): """Store solution on current timestep to XDMF file.""" timefolder = path.join(newfolder, 'Timeseries') if output_timeseries_as_vector: # project or store velocity to vector function space for comp, tstepfile in tstepfiles.iteritems(): if comp == "u": V = q_['u0'].function_space() # First time around create vector function and assigners if not hasattr(tstepfile, 'uv'): tstepfile.uv = AssignedVectorFunction(u_) # Assign solution to vector tstepfile.uv() # Store solution vector tstepfile << (tstepfile.uv, float(tstep)) elif comp in q_: tstepfile << (q_[comp], float(tstep)) else: tstepfile << (tstepfile.function, float(tstep)) else: for comp, tstepfile in tstepfiles.iteritems(): tstepfile << (q_[comp], float(tstep)) if MPI.rank(mpi_comm_world()) == 0: if not path.exists(path.join(timefolder, "params.dat")): f = open(path.join(timefolder, 'params.dat'), 'w') cPickle.dump(NS_parameters, f)
def save_tstep_solution_h5(tstep, q_, u_, newfolder, tstepfiles, constrained_domain, output_timeseries_as_vector, u_components, AssignedVectorFunction, scalar_components, NS_parameters, NS_expressions): """Store solution on current timestep to XDMF file.""" timefolder = path.join(newfolder, 'Timeseries') if output_timeseries_as_vector: # project or store velocity to vector function space for comp, tstepfile in six.iteritems(tstepfiles): if comp == "u": V = q_['u0'].function_space() # First time around create vector function and assigners if "uv" not in NS_expressions.keys(): NS_expressions["uv"] = AssignedVectorFunction(u_) # Assign solution to vector NS_expressions["uv"]() # Store solution vector tstepfile.write(NS_expressions["uv"], float(tstep)) elif comp in q_: tstepfile.write(q_[comp], float(tstep)) else: tstepfile.write(tstepfile.function, float(tstep)) else: for comp, tstepfile in six.iteritems(tstepfiles): tstepfile.write(q_[comp], float(tstep)) if MPI.rank(MPI.comm_world) == 0: if not path.exists(path.join(timefolder, "params.dat")): f = open(path.join(timefolder, 'params.dat'), 'wb') pickle.dump(NS_parameters, f)
def test_multi_ps_vector(mesh): """Tests point source PointSource(V, source) for mulitple point sources applied to a vector for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. """ c_ids = [0, 1, 2] rank = MPI.rank(mesh.mpi_comm()) V = FunctionSpace(mesh, "CG", 1) v = TestFunction(V) b = assemble(Constant(0.0)*v*dx) source = [] if rank == 0: for c_id in c_ids: cell = Cell(mesh, c_id) point = cell.midpoint() source.append((point, 10.0)) ps = PointSource(V, source) ps.apply(b) # Checks b sums to correct value b_sum = b.sum() assert round(b_sum - len(c_ids)*10.0) == 0
def __init__(self, V, options=None): # See if we have dofmap if not is_function_space(V): raise ValueError("V is not a function space.") # Only allow 2d and 3d meshes if V.mesh().geometry().dim() == 1: raise ValueError("Only 2d and 3d meshes are supported.") # Get MPI info try: from dolfin import mpi_comm_world self.mpi_size = MPI.size(mpi_comm_world()) self.mpi_rank = MPI.rank(mpi_comm_world()) except ImportError: self.mpi_size = MPI.num_processes() self.mpi_rank = MPI.process_number() # Analyze the space V self.V = V self.dofmaps = extract_dofmaps(self.V) self.bounds = bounds(self.V) # Rewrite default plotting options if they are provided by user self.options = {"colors": {"mesh_entities": "hsv", "mesh": "Blues"}, "xkcd": False, "markersize": 40} if options is not None: self.options.update(options) # Keep track of the plots self.plots = []
def create_initial_folders(folder, restart_folder, sys_comp, tstep, info_red, scalar_components, output_timeseries_as_vector, **NS_namespace): """Create necessary folders.""" info_red("Creating initial folders") # To avoid writing over old data create a new folder for each run if MPI.rank(MPI.comm_world) == 0: try: makedirs(folder) except OSError: pass MPI.barrier(MPI.comm_world) newfolder = path.join(folder, 'data') if restart_folder: newfolder = path.join(newfolder, restart_folder.split('/')[-2]) else: if not path.exists(newfolder): newfolder = path.join(newfolder, '1') else: previous = listdir(newfolder) previous = max(map(eval, previous)) if previous else 0 newfolder = path.join(newfolder, str(previous + 1)) MPI.barrier(MPI.comm_world) if MPI.rank(MPI.comm_world) == 0: if not restart_folder: #makedirs(path.join(newfolder, "Voluviz")) #makedirs(path.join(newfolder, "Stats")) #makedirs(path.join(newfolder, "VTK")) makedirs(path.join(newfolder, "Timeseries")) makedirs(path.join(newfolder, "Checkpoint")) tstepfolder = path.join(newfolder, "Timeseries") tstepfiles = {} comps = sys_comp if output_timeseries_as_vector: comps = ['p', 'u'] + scalar_components for ui in comps: tstepfiles[ui] = XDMFFile(MPI.comm_world, path.join( tstepfolder, ui + '_from_tstep_{}.xdmf'.format(tstep))) tstepfiles[ui].parameters["rewrite_function_mesh"] = False tstepfiles[ui].parameters["flush_output"] = True return newfolder, tstepfiles
def _create_tempdir(request): # Get directory name of test_foo.py file testfile = request.module.__file__ testfiledir = os.path.dirname(os.path.abspath(testfile)) # Construct name test_foo_tempdir from name test_foo.py testfilename = os.path.basename(testfile) outputname = testfilename.replace(".py", "_tempdir") # Get function name test_something from test_foo.py function = request.function.__name__ # Join all of these to make a unique path for this test function basepath = os.path.join(testfiledir, outputname) path = os.path.join(basepath, function) # Add a sequence number to avoid collisions when tests are otherwise parameterized if MPI.rank(mpi_comm_world()) == 0: _create_tempdir._sequencenumber[path] += 1 sequencenumber = _create_tempdir._sequencenumber[path] sequencenumber = MPI.sum(mpi_comm_world(), sequencenumber) else: sequencenumber = MPI.sum(mpi_comm_world(), 0) path += "__" + str(sequencenumber) # Delete and re-create directory on root node if MPI.rank(mpi_comm_world()) == 0: # First time visiting this basepath, delete the old and create a new if basepath not in _create_tempdir._basepaths: _create_tempdir._basepaths.add(basepath) #if os.path.exists(basepath): # shutil.rmtree(basepath) # Make sure we have the base path test_foo_tempdir for this test_foo.py file if not os.path.exists(basepath): os.mkdir(basepath) # Delete path from old test run #if os.path.exists(path): # shutil.rmtree(path) # Make sure we have the path for this test execution: e.g. test_foo_tempdir/test_something__3 if not os.path.exists(path): os.mkdir(path) MPI.barrier(mpi_comm_world()) return path
def test_GaussDivergence(mesh): dim = mesh.topology().dim() expr = ["%s*x[%s]" % (dim, i) for i in range(dim)] V = VectorFunctionSpace(mesh, "CG", 1) u = interpolate(Expression(tuple(expr)), V) divu = gauss_divergence(u) DIVU = divu.vector().array() point_0 = all(abs(DIVU - dim * dim) < 1e-13) if MPI.rank(mpi_comm_world()) == 0: assert point_0
def test_GaussDivergence(mesh): dim = mesh.topology().dim() expr = ["%s*x[%s]" % (dim,i) for i in range(dim)] V = VectorFunctionSpace(mesh, 'CG', 1) u = interpolate(Expression(tuple(expr), degree=1), V) divu = gauss_divergence(u) DIVU = divu.vector().get_local() point_0 = all(abs(DIVU - dim*dim) < 1E-13) if MPI.rank(MPI.comm_world) == 0: assert point_0
def save_checkpoint_solution_h5(tstep, q_, q_1, newfolder, u_components, NS_parameters): """Overwrite solution in Checkpoint folder. For safety reasons, in case the solver is interrupted, take backup of solution first. Must be restarted using the same mesh-partitioning. This will be fixed soon. (MM) """ checkpointfolder = path.join(newfolder, "Checkpoint") NS_parameters["num_processes"] = MPI.size(MPI.comm_world) if MPI.rank(MPI.comm_world) == 0: if path.exists(path.join(checkpointfolder, "params.dat")): system('cp {0} {1}'.format(path.join(checkpointfolder, "params.dat"), path.join(checkpointfolder, "params_old.dat"))) f = open(path.join(checkpointfolder, "params.dat"), 'wb') pickle.dump(NS_parameters, f) MPI.barrier(MPI.comm_world) for ui in q_: h5file = path.join(checkpointfolder, ui + '.h5') oldfile = path.join(checkpointfolder, ui + '_old.h5') # For safety reasons... if path.exists(h5file): if MPI.rank(MPI.comm_world) == 0: system('cp {0} {1}'.format(h5file, oldfile)) MPI.barrier(MPI.comm_world) ### newfile = HDF5File(MPI.comm_world, h5file, 'w') newfile.flush() newfile.write(q_[ui].vector(), '/current') if ui in u_components: newfile.write(q_1[ui].vector(), '/previous') if path.exists(oldfile): if MPI.rank(MPI.comm_world) == 0: system('rm {0}'.format(oldfile)) MPI.barrier(MPI.comm_world) newfile.close() if MPI.rank(MPI.comm_world) == 0 and path.exists(path.join(checkpointfolder, "params_old.dat")): system('rm {0}'.format(path.join(checkpointfolder, "params_old.dat")))
def test_Probes_functionspace_2D(V2): u0 = interpolate(Expression('x[0]'), V2) x = array([[0.5, 0.5], [0.4, 0.4], [0.3, 0.3]]) p = Probes(x.flatten(), V2) # Probe twice p(u0) p(u0) # Check both snapshots p0 = p.array(N=0) if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0] - 0.5, 7) == 0 assert round(p0[1] - 0.4, 7) == 0 assert round(p0[2] - 0.3, 7) == 0 p0 = p.array(N=1) if MPI.rank(mpi_comm_world()) == 0: assert round(p0[0] - 0.5, 7) == 0 assert round(p0[1] - 0.4, 7) == 0 assert round(p0[2] - 0.3, 7) == 0
def test_StatisticsProbes_vector_3D(VF3): u0 = interpolate(Expression(('x[0]', 'x[1]', 'x[2]'), degree=1), VF3) x = array([[0.5, 0.25, 0.25], [0.4, 0.4, 0.4], [0.3, 0.3, 0.3]]) probes = StatisticsProbes(x.flatten(), VF3) for i in range(5): probes(u0) p = probes.array() if MPI.rank(mpi_comm_world()) == 0: assert round(p[0,0] - 2.5, 7) == 0 assert round(p[0,4] - 0.3125, 7) == 0
def test_StatisticsProbes_segregated_2D(V2): u0 = interpolate(Expression('x[0]', degree=1), V2) v0 = interpolate(Expression('x[1]', degree=1), V2) x = array([[0.5, 0.25], [0.4, 0.4], [0.3, 0.3]]) probes = StatisticsProbes(x.flatten(), V2, True) for i in range(5): probes(u0, v0) p = probes.array() if MPI.rank(mpi_comm_world()) == 0: assert round(p[0,0] - 2.5, 7) == 0 assert round(p[0,4] - 0.625, 7) == 0
def check_if_kill(folder): """Check if user has put a file named killoasis in folder.""" found = 0 if 'killoasis' in listdir(folder): found = 1 collective = MPI.sum(mpi_comm_world(), found) if collective > 0: if MPI.rank(mpi_comm_world()) == 0: remove(path.join(folder, 'killoasis')) info_red('killoasis Found! Stopping simulations cleanly...') return True else: return False
def check_if_reset_statistics(folder): """Check if user has put a file named resetoasis in folder.""" found = 0 if 'resetoasis' in listdir(folder): found = 1 collective = MPI.sum(mpi_comm_world(), found) if collective > 0: if MPI.rank(mpi_comm_world()) == 0: remove(path.join(folder, 'resetoasis')) info_red('resetoasis Found!') return True else: return False
def __init__(self, V, Vm, bc, bcadj, \ RHSinput=[], ObsOp=[], UD=[], Regul=[], Data=[], plot=False, \ mycomm=None): # Define test, trial and all other functions self.trial = TrialFunction(V) self.test = TestFunction(V) self.mtrial = TrialFunction(Vm) self.mtest = TestFunction(Vm) self.rhs = Function(V) self.m = Function(Vm) self.mcopy = Function(Vm) self.srchdir = Function(Vm) self.delta_m = Function(Vm) self.MG = Function(Vm) self.Grad = Function(Vm) self.Gradnorm = 0.0 self.lenm = len(self.m.vector().array()) self.u = Function(V) self.ud = Function(V) self.diff = Function(V) self.p = Function(V) # Define weak forms to assemble A, C and E self._wkforma() self._wkformc() self._wkforme() # Store other info: self.ObsOp = ObsOp self.UD = UD self.reset() # Initialize U, C and E to [] self.Data = Data self.GN = 1.0 # GN = 0.0 => GN Hessian; = 1.0 => full Hessian # Operators and bc LinearOperator.__init__(self, self.delta_m.vector(), \ self.delta_m.vector()) self.bc = bc self.bcadj = bcadj self._assemble_solverM(Vm) self.assemble_A() self.assemble_RHS(RHSinput) self.Regul = Regul # Counters, tolerances and others self.nbPDEsolves = 0 # Updated when solve_A called self.nbfwdsolves = 0 # Counter for plots self.nbadjsolves = 0 # Counter for plots self._set_plots(plot) # MPI: self.mycomm = mycomm try: self.myrank = MPI.rank(self.mycomm) except: self.myrank = 0
def test_StatisticsProbes_segregated_3D(V3): u0 = interpolate(Expression('x[0]', degree=1), V3) v0 = interpolate(Expression('x[1]', degree=1), V3) w0 = interpolate(Expression('x[2]', degree=1), V3) x = array([[0.5, 0.25, 0.25], [0.4, 0.4, 0.4], [0.3, 0.3, 0.3]]) probes = StatisticsProbes(x.flatten(), V3, True) for i in range(5): probes(u0, v0, w0) p = probes.array() if MPI.rank(MPI.comm_world) == 0: assert round(p[0,0] - 2.5, 7) == 0 assert round(p[0,4] - 0.3125, 7) == 0
def test_Probes_functionspace_2D(): mesh = UnitSquareMesh(4, 4) V = FunctionSpace(mesh, 'CG', 1) u0 = interpolate(Expression('x[0]'), V) x = array([[0.5, 0.5], [0.4, 0.4], [0.3, 0.3]]) p = Probes(x.flatten(), V) # Probe twice p(u0) p(u0) # Check both snapshots p0 = p.array(N=0) if MPI.rank(mpi_comm_world()) == 0: nose.tools.assert_almost_equal(p0[0], 0.5) nose.tools.assert_almost_equal(p0[1], 0.4) nose.tools.assert_almost_equal(p0[2], 0.3) p0 = p.array(N=1) if MPI.rank(mpi_comm_world()) == 0: nose.tools.assert_almost_equal(p0[0], 0.5) nose.tools.assert_almost_equal(p0[1], 0.4) nose.tools.assert_almost_equal(p0[2], 0.3)
def __init__(self, model): # Process number self.MPI_rank = MPI.rank(mpi_comm_world()) ### Get a few fields and parameters from the model # Effective pressure N = model.N # Sliding speed u_b = model.u_b # Initial model time t0 = model.t # Rate factor A = model.pcs['A'] # Distance between bumps l_r = model.pcs['l_r'] # Bump height h_r = model.h_r # Initial sheet height h0 = model.h.vector().array() # Bump height vector h_r_n = h_r.vector().array() ### Set up the sheet height ODE # Right hand side for the gap height ODE def rhs(t, h_n): # Ensure that the sheet height is positive h_n[h_n < 0.0] = 0.0 # Sheet opening term w_n = u_b.vector().array() * (h_r_n - h_n) / l_r # Ensure that the opening term is non-negative w_n[w_n < 0.0] = 0.0 # Sheet closure term v_n = A * h_n * N.vector().array()**3 # Return the time rate of change of the sheet dhdt = w_n - v_n return dhdt # Set up ODE solver ode_solver = ode(rhs).set_integrator('vode', method='adams', max_step = 60.0 * 5.0) ode_solver.set_initial_value(h0, t0) ### Set local variables self.ode_solver = ode_solver self.model = model
def print_text(text, color=None, atrb=0, cls=None): """ Print text ``text`` from calling class ``cls`` to the screen. :param text: the text to print :param color: the color of the text to print :param atrb: attributes to send use by ``colored`` package :param cls: the calling class :type text: string :type color: string :type atrb: int :type cls: object """ if MPI.rank(mpi_comm_world())==0: print(get_text(text, color, atrb, cls))
def test_multi_ps_matrix_node_vector_fs(mesh): """Tests point source applied to a matrix with given constructor PointSource(V, source) and a vector function space when points placed at 3 vertices for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. """ point = [0.0, 0.5, 1.0] rank = MPI.rank(mesh.mpi_comm()) V = VectorFunctionSpace(mesh, "CG", 1, dim=2) u, v = TrialFunction(V), TestFunction(V) w = Function(V) A = assemble(Constant(0.0)*dot(u, v)*dx) dim = mesh.geometry().dim() source = [] point_coords = np.zeros(dim) for p in point: for i in range(dim): point_coords[i - 1] = p if rank == 0: source.append((Point(point_coords), 10.0)) ps = PointSource(V, source) ps.apply(A) # Checks array sums to correct value A.get_diagonal(w.vector()) a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array())) assert round(a_sum - 2*len(point)*10) == 0 # Check if coordinates are in portion of mesh and if so check that # diagonal components sum to the correct value. mesh_coords = V.tabulate_dof_coordinates() for p in point: for i in range(dim): point_coords[i] = p j = 0 for i in range(len(mesh_coords)//(dim)): mesh_coords_check = mesh_coords[j:j+dim-1] if np.array_equal(point_coords, mesh_coords_check) is True: assert np.round(w.vector()[j//(dim)] - 10.0) == 0.0 j += dim
def __init__(self, fns, fs, t = 0.0, dt = 0.05, dt_max = 0.1, tol = 1e-3, error_fn = None, output = True) : # Initial Time self.t = t # A list of Fenics functions (the unknowns) self.fns = fns # The slope function coorresponding to each function self.fs = fs # The tolerance used for adaptive time stepping self.tol = tol # Set the initial time step self.dt = dt # The maximum allowable time step self.dt_max = dt_max # Time coefficients for each k_i self.t_cos = np.array([0., 1/4., 3/8., 12/13., 1., 1/2.]) # A vector of concatenated solution vectors self.xs = np.hstack(np.array([self.fns[i].vector().array() for i in range(len(self.fns))]).flat) # A list containing the start index of every function in self.xs self.fn_indexes = np.cumsum([len(self.fns[i].vector().array()) for i in range(len(self.fns) - 1)]) # Specifies whether to output info. such as the current time, time step, etc. self.output = output # MPI process rank self.MPI_rank = MPI.rank(mpi_comm_world()) # The coefficients for computing each k_i self.k_cos = np.array([ [], [1/4.], [3/32., 9/32.], [1932/2197., -7200/2197., 7296/2197.], [439/216., -8., 3680/513., -845/4104.], [-8/27., 2., -3544/2565., 1859/4104., -11/40.] ]) # Coefficients for computing two RK solutions x1 and x2 of different orders given # the k_i's self.x1_cos = np.array([16/135., 0., 6656/12825., 28561/56430., -9/50., 2/55.]) self.x2_cos = np.array([25/216., 0., 1408/2565., 2197/4101., -1/5., 0.]) # Function for estimating the error given two solutions x1 and x2 of different orders self.error_fn = self.default_error if error_fn != None : self.error_fn = error_fn
def save_tstep_solution_h5(tstep, q_, u_, newfolder, tstepfiles, constrained_domain, output_timeseries_as_vector, u_components, scalar_components, NS_parameters): """Store solution on current timestep to XDMF file.""" timefolder = path.join(newfolder, 'Timeseries') if output_timeseries_as_vector: # project or store velocity to vector function space for comp, tstepfile in tstepfiles.iteritems(): if comp == "u": if not hasattr(tstepfile, 'uv'): # First time around only V = q_['u0'].function_space() Vv = VectorFunctionSpace(V.mesh(), V.ufl_element().family(), V.ufl_element().degree(), constrained_domain=constrained_domain) tstepfile.uv = Function(Vv) tstepfile.d = dict((ui, Vv.sub(i).dofmap().collapse(Vv.mesh())[1]) for i, ui in enumerate(u_components)) # The short but timeconsuming way: #tstepfile.uv.assign(project(u_, Vv)) # Or the faster, but more comprehensive way: for ui in u_components: q_[ui].update() vals = tstepfile.d[ui].values() keys = tstepfile.d[ui].keys() tstepfile.uv.vector()[vals] = q_[ui].vector()[keys] tstepfile << (tstepfile.uv, float(tstep)) elif comp in q_: tstepfile << (q_[comp], float(tstep)) else: tstepfile << (tstepfile.function, float(tstep)) else: for comp, tstepfile in tstepfiles.iteritems(): tstepfile << (q_[comp], float(tstep)) if MPI.rank(mpi_comm_world()) == 0: if not path.exists(path.join(timefolder, "params.dat")): f = open(path.join(timefolder, 'params.dat'), 'w') cPickle.dump(NS_parameters, f)
Ricker wavelet at the center of a unit square with dashpot absorbing boundary conditions on all 4 boundaries """ import sys from os.path import splitext, isdir from shutil import rmtree from fenicstools.plotfenics import PlotFenics from fenicstools.acousticwave import AcousticWave from fenicstools.sourceterms import PointSources, RickerWavelet try: from dolfin import UnitSquareMesh, FunctionSpace, Constant, DirichletBC, \ interpolate, Expression, Function, SubDomain, MPI, mpi_comm_world mycomm = mpi_comm_world() myrank = MPI.rank(mycomm) except: from dolfin import UnitSquareMesh, FunctionSpace, Constant, DirichletBC, \ interpolate, Expression, Function, SubDomain mycomm = None myrank = 0 RR = [1, 2, 3, 4] ERROR = [] # Inputs: Nxy = 100 mesh = UnitSquareMesh(Nxy, Nxy, "crossed") h = 1. / Nxy Vl = FunctionSpace(mesh, 'Lagrange', 1) Dt = 3e-4 #Dt = h/(r*alpha)
def traction_test(ell=0.05, ell_e=.1, degree=1, n=3, nu=0., load_min=0, load_max=2, loads=None, nsteps=20, Lx=1., Ly=0.1, outdir="outdir", postfix='', savelag=1, sigma_D0=1., periodic=False, continuation=False, checkstability=True, configString='', test=True): # constants # ell = ell Lx = Lx load_min = load_min load_max = load_max nsteps = nsteps outdir = outdir loads = loads savelag = 1 nu = dolfin.Constant(nu) ell = dolfin.Constant(ell) ell_e = ell_e E = dolfin.Constant(1.0) K = E.values()[0] / ell_e**2. sigma_D0 = E n = n # h = ell.values()[0]/n h = max(ell.values()[0] / n, .005) cell_size = h continuation = continuation isPeriodic = periodic config = json.loads(configString) if configString != '' else '' cmd_parameters = { 'material': { "ell": ell.values()[0], "ell_e": ell_e, "K": K, "E": E.values()[0], "nu": nu.values()[0], "sigma_D0": sigma_D0.values()[0] }, 'geometry': { 'Lx': Lx, 'Ly': Ly, 'n': n, }, 'experiment': { 'periodic': isPeriodic, 'signature': '' }, 'stability': { 'checkstability': checkstability, 'continuation': continuation }, 'time_stepping': { 'load_min': load_min, 'load_max': load_max, 'nsteps': nsteps, 'outdir': outdir, 'postfix': postfix, 'savelag': savelag }, 'alt_min': {}, "code": {} } # -------------------- for par in parameters: parameters[par].update(cmd_parameters[par]) if config: # import pdb; pdb.set_trace() for par in config: parameters[par].update(config[par]) # else: # parameters['material']['ell_e'] = # import pdb; pdb.set_trace() Lx = parameters['geometry']['Lx'] Ly = parameters['geometry']['Ly'] ell = parameters['material']['ell'] ell_e = parameters['material']['ell_e'] BASE_DIR = os.path.dirname(os.path.realpath(__file__)) fname = "film" print(BASE_DIR) os.path.isfile(fname) signature = hashlib.md5(str(parameters).encode('utf-8')).hexdigest() print('Signature is: ' + signature) # if parameters['experiment']['test'] == True: outdir += '-{}'.format(cmd_parameters['time_stepping']['postfix']) # else: outdir += '-{}{}'.format(signature, cmd_parameters['time_stepping']['postfix']) parameters['time_stepping']['outdir'] = outdir Path(outdir).mkdir(parents=True, exist_ok=True) print('Outdir is: ' + outdir) with open(os.path.join(outdir, 'rerun.sh'), 'w') as f: configuration = deepcopy(parameters) configuration['time_stepping'].pop('outdir') str(configuration).replace("\'True\'", "True").replace("\'False\'", "False") rerun_cmd = 'python3 {} --config="{}"'.format( os.path.basename(__file__), configuration) f.write(rerun_cmd) with open(os.path.join(outdir, 'parameters.pkl'), 'w') as f: json.dump(parameters, f) with open(os.path.join(outdir, 'signature.md5'), 'w') as f: f.write(signature) print(parameters) # ------------------ geometry_parameters = parameters['geometry'] geom_signature = hashlib.md5( str(geometry_parameters).encode('utf-8')).hexdigest() meshfile = "%s/meshes/circle-%s.xml" % (BASE_DIR, geom_signature) # cmd_parameters['experiment']['signature']=signature meshsize = parameters['material']['ell'] / parameters['geometry']['n'] d = { 'rad': parameters['geometry']['Lx'], 'Ly': parameters['geometry']['Ly'], 'meshsize': meshsize } if os.path.isfile(meshfile): print("Meshfile %s exists" % meshfile) mesh = dolfin.Mesh("meshes/circle-%s.xml" % (geom_signature)) else: print("Creating meshfile: %s" % meshfile) print("DEBUG: parameters: %s" % parameters['geometry']) mesh_template = open('templates/circle_template.geo') src = Template(mesh_template.read()) geofile = src.substitute(d) if MPI.rank(MPI.comm_world) == 0: with open("meshes/circle-%s" % geom_signature + ".geo", 'w') as f: f.write(geofile) cmd1 = 'gmsh meshes/circle-{}.geo -2 -o meshes/circle-{}.msh'.format( geom_signature, geom_signature) cmd2 = 'dolfin-convert -i gmsh meshes/circle-{}.msh meshes/circle-{}.xml'.format( geom_signature, geom_signature) print( 'Unable to handle mesh generation at the moment, please generate the mesh and test again.' ) print(cmd1) print(cmd2) sys.exit() print(check_output([cmd1], shell=True) ) # run in shell mode in case you are not run in terminal Popen([cmd2], stdout=PIPE, shell=True).communicate() mesh = Mesh('meshes/circle-{}.xml'.format(geom_signature)) mesh_xdmf = XDMFFile("meshes/circle-%s.xdmf" % (geom_signature)) mesh_xdmf.write(mesh) # with pygmsh.geo.Geometry() as geom: # circle = geom.add_circle( # [0.0, 0.0, 0.0], # 1.0, # mesh_size=0.1, # num_sections=4, # # If compound==False, the section borders have to be points of the # # discretization. If using a compound circle, they don't; gmsh can # # choose by itself where to point the circle points. # compound=True, # ) # geom.add_physical(circle.plane_surface, "disk") # # # mesh = geom.generate_mesh() # mesh.write("out.xdmf") # mesh.write("out.xml") # geom = mshr.Rectangle(dolfin.Point(-Lx/2., -Ly/2.), dolfin.Point(Lx/2., Ly/2.)) # mesh = mshr.generate_mesh(geom, n * int(float(Lx / ell))) print(meshfile) mesh_xdmf = dolfin.XDMFFile("meshes/%s-%s.xdmf" % (fname, geom_signature)) mesh_xdmf.write(mesh) if rank == 0: meshf = dolfin.File(os.path.join(outdir, "mesh.xml")) meshf << mesh V_u = dolfin.VectorFunctionSpace(mesh, "CG", 1) V_alpha = dolfin.FunctionSpace(mesh, "CG", 1) u = dolfin.Function(V_u, name="Total displacement") alpha = dolfin.Function(V_alpha, name="Damage") bcs_alpha = [] # Rectangle # bcs_u = [DirichletBC(V_u, Constant((0., 0)), '(near(x[0], %f) or near(x[0], %f))'%(-Lx/2., Lx/2.))] # Circle bcs_u = [DirichletBC(V_u, Constant((0., 0.)), 'on_boundary')] state = [u, alpha] Z = dolfin.FunctionSpace( mesh, dolfin.MixedElement([u.ufl_element(), alpha.ufl_element()])) z = dolfin.Function(Z) v, beta = dolfin.split(z) dx = dolfin.Measure("dx", metadata=form_compiler_parameters, domain=mesh) ds = dolfin.Measure("ds") # Files for output file_out = dolfin.XDMFFile(os.path.join(outdir, "output.xdmf")) file_eig = dolfin.XDMFFile(os.path.join(outdir, "perturbations.xdmf")) file_con = dolfin.XDMFFile(os.path.join(outdir, "continuation.xdmf")) file_bif = dolfin.XDMFFile( os.path.join(outdir, "bifurcation_postproc.xdmf")) for f in [file_out, file_eig, file_con, file_bif]: f.parameters["functions_share_mesh"] = True f.parameters["flush_output"] = True # Problem foundation_density = 1. / 2. * 1. / ell_e**2. * dot(u, u) model = DamagePrestrainedElasticityModel( state, E, nu, ell, sigma_D0, user_functional=foundation_density, eps0t=Expression([['t', 0.], [0., 't']], t=0., degree=0)) # import pdb; pdb.set_trace() model.dx = dx model.ds = ds energy = model.total_energy_density(u, alpha) * dx # Alternate minimization solver solver = solvers.AlternateMinimizationSolver( energy, [u, alpha], [bcs_u, bcs_alpha], parameters=parameters['alt_min']) rP = model.rP(u, alpha, v, beta) * dx + 1 / ell_e**2. * dot(v, v) * dx rN = model.rN(u, alpha, beta) * dx # stability = StabilitySolver(mesh, energy, [u, alpha], [bcs_u, bcs_alpha], z, parameters = parameters['stability']) stability = StabilitySolver(mesh, energy, [u, alpha], [bcs_u, bcs_alpha], z, parameters=parameters['stability'], rayleigh=[rP, rN]) load_steps = np.linspace(load_min, load_max, parameters['time_stepping']['nsteps']) if loads: load_steps = loads time_data = [] linesearch = LineSearch(energy, [u, alpha]) alpha_old = dolfin.Function(alpha.function_space()) lmbda_min_prev = 0.000001 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurc_i = 0 alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) for it, load in enumerate(load_steps): model.eps0t.t = load alpha_old.assign(alpha) ColorPrint.print_warn('Solving load t = {:.2f}'.format(load)) # First order stability conditions (time_data_i, am_iter) = solver.solve() # Second order stability conditions (stable, negev) = stability.solve(solver.problem_alpha.lb) ColorPrint.print_pass( 'Current state is{}stable'.format(' ' if stable else ' un')) mineig = stability.mineig if hasattr(stability, 'mineig') else 0.0 print('lmbda min', lmbda_min_prev) print('mineig', mineig) Deltav = (mineig - lmbda_min_prev) if hasattr(stability, 'eigs') else 0 if (mineig + Deltav) * (lmbda_min_prev + dolfin.DOLFIN_EPS) < 0 and not bifurcated: bifurcated = True # save 3 bif modes print('About to bifurcate load ', load, 'step', it) bifurcation_loads.append(load) print('DEBUG: decide what to do') # save_current_bifurcation = True bifurc_i += 1 lmbda_min_prev = mineig if hasattr(stability, 'mineig') else 0. if stable: solver.update() else: # Continuation iteration = 1 while stable == False: # linesearch perturbation_v = stability.perturbation_v perturbation_beta = stability.perturbation_beta h_opt, (hmin, hmax), energy_perturbations = linesearch.search( [u, alpha, alpha_old], perturbation_v, perturbation_beta) if h_opt != 0: save_current_bifurcation = True alpha_bif.assign(alpha) alpha_bif_old.assign(alpha_old) # admissible uval = u.vector()[:] + h_opt * perturbation_v.vector()[:] aval = alpha.vector( )[:] + h_opt * perturbation_beta.vector()[:] u.vector()[:] = uval alpha.vector()[:] = aval u.vector().vec().ghostUpdate() alpha.vector().vec().ghostUpdate() # import pdb; pdb.set_trace() (time_data_i, am_iter) = solver.solve() (stable, negev) = stability.solve(alpha_old) ColorPrint.print_pass( ' Continuation iteration {}, current state is{}stable' .format(iteration, ' ' if stable else ' un')) iteration += 1 else: # warn ColorPrint.print_warn( 'Found zero increment, we are stuck in the matrix') ColorPrint.print_warn('Continuing load program') break solver.update() # stable == True time_data_i["load"] = load time_data_i["stable"] = stable time_data_i["dissipated_energy"] = dolfin.assemble( model.damage_dissipation_density(alpha) * dx) time_data_i["foundation_energy"] = dolfin.assemble( 1. / 2. * 1 / ell_e**2. * dot(u, u) * dx) time_data_i["membrane_energy"] = dolfin.assemble( model.elastic_energy_density(model.eps(u), alpha) * dx) time_data_i["elastic_energy"] = time_data_i[ "membrane_energy"] + time_data_i["foundation_energy"] time_data_i["eigs"] = stability.eigs if hasattr(stability, 'eigs') else np.inf time_data_i["stable"] = stability.stable time_data_i["# neg ev"] = stability.negev _sigma = model.stress(model.eps(u), alpha) e1 = dolfin.Constant([1, 0]) _snn = dolfin.dot(dolfin.dot(_sigma, e1), e1) time_data_i["sigma"] = 1 / Ly * dolfin.assemble(_snn * model.ds(1)) time_data_i["S(alpha)"] = dolfin.assemble(1. / (model.a(alpha)) * model.dx) time_data_i["A(alpha)"] = dolfin.assemble((model.a(alpha)) * model.dx) time_data_i["avg_alpha"] = 1 / dolfin.assemble( dolfin.project(Constant(1.), V_alpha) * model.dx) * dolfin.assemble(alpha * model.dx) ColorPrint.print_pass( "Time step {:.4g}: it {:3d}, err_alpha={:.4g}".format( time_data_i["load"], time_data_i["iterations"], time_data_i["alpha_error"])) time_data.append(time_data_i) time_data_pd = pd.DataFrame(time_data) if np.mod(it, savelag) == 0: with file_out as f: f.write(alpha, load) f.write(u, load) # with file_out as f: f.write_checkpoint(alpha, "alpha-{}".format(it), 0, append=True) print('DEBUG: written step ', it) if save_current_bifurcation: # modes = np.where(stability.eigs < 0)[0] time_data_i['h_opt'] = h_opt time_data_i['max_h'] = hmax time_data_i['min_h'] = hmin with file_bif as file: # leneigs = len(modes) # maxmodes = min(3, leneigs) beta0v = dolfin.project(stability.perturbation_beta, V_alpha) print('DEBUG: irrev ', alpha.vector() - alpha_old.vector()) file.write_checkpoint(beta0v, 'beta0', 0, append=True) file.write_checkpoint(alpha_bif_old, 'alpha-old', 0, append=True) file.write_checkpoint(alpha_bif, 'alpha-bif', 0, append=True) file.write_checkpoint(alpha, 'alpha', 0, append=True) np.save(os.path.join(outdir, 'energy_perturbations'), energy_perturbations, allow_pickle=True, fix_imports=True) with file_eig as file: _v = dolfin.project( dolfin.Constant(h_opt) * perturbation_v, V_u) _beta = dolfin.project( dolfin.Constant(h_opt) * perturbation_beta, V_alpha) _v.rename('perturbation displacement', 'perturbation displacement') _beta.rename('perturbation damage', 'perturbation damage') # import pdb; pdb.set_trace() f.write(_v, load) f.write(_beta, load) file.write_checkpoint(_v, 'perturbation_v', 0, append=True) file.write_checkpoint(_beta, 'perturbation_beta', 0, append=True) time_data_pd.to_json(os.path.join(outdir, "time_data.json")) # user_postprocess_timestep(alpha, parameters, load, xresol = 100) plt.figure() dolfin.plot(alpha) plt.savefig(os.path.join(outdir, "alpha.png")) plt.figure() dolfin.plot(u, mode="displacement") plt.savefig(os.path.join(outdir, "u.png")) _nu = parameters['material']['nu'] _E = parameters['material']['E'] _w1 = parameters['material']['sigma_D0']**2. / parameters['material']['E'] tc = np.sqrt(2 * _w1 / (_E * (1. - 2. * _nu) * (1. + _nu))) if parameters['stability']['checkstability'] == 'True': pp.plot_spectrum(parameters, outdir, time_data_pd.sort_values('load'), tc) # plt.show() collect_timings(outdir, t0) print(time_data_pd) return time_data_pd
def create_slice(basemesh, point, normal, closest_region=False, crinkle_clip=False): """Create a slicemesh from a basemesh. :param basemesh: Mesh to slice :param point: Point in slicing plane :param normal: Normal to slicing plane :param closest_region: Set to True to extract disjoint region closest to specified point :param crinkle_clip: Set to True to return mesh of same topological dimension as basemesh .. note:: Only 3D-meshes currently supported for slicing. .. warning:: Slice-instances are intended for visualization only, and may produce erronous results if used for computations. """ assert basemesh.geometry().dim() == 3, "Can only slice 3D-meshes." P = np.array([point[0], point[1], point[2]], dtype=np.double) # Create unit normal n = np.array([normal[0],normal[1], normal[2]]) n = n/np.linalg.norm(n) #self.n = Constant((n[0], n[1], n[2])) # Calculate the distribution of vertices around the plane # (sign of np.dot(p-P, n) determines which side of the plane p is on) vsplit = np.dot(basemesh.coordinates()-P, n) # Count each cells number of vertices on the "positive" side of the plane # Only cells with vertices on both sides of the plane intersect the plane operator = np.less npos = np.sum(vsplit[basemesh.cells()] < 0, 1) intersection_cells = basemesh.cells()[(npos > 0) & (npos < 4)] if len(intersection_cells) == 0: # Try to put "zeros" on other side of plane # FIXME: handle cells with vertices exactly intersecting the plane in a more robust manner. operator = np.greater npos = np.sum(vsplit[basemesh.cells()] > 0, 1) #cell_indices = (npos > 0) & (npos < 4) intersection_cells = basemesh.cells()[(npos > 0) & (npos < 4)] if crinkle_clip: cf = CellFunction("size_t", basemesh) cf.set_all(0) cf.array()[(npos>0) & (npos<4)] = 1 mesh = create_submesh(basemesh, cf, 1) else: def add_cell(cells, cell): # Split cell into triangles for i in xrange(len(cell)-2): cells.append(cell[i:i+3]) cells = [] index = 0 indexes = {} for c in intersection_cells: a = operator(vsplit[c], 0) positives = c[np.where(a==True)[0]] negatives = c[np.where(a==False)[0]] cell = [] for pp_ind in positives: pp = basemesh.coordinates()[pp_ind] for pn_ind in negatives: pn = basemesh.coordinates()[pn_ind] if (pp_ind, pn_ind) not in indexes: # Calculate intersection point with the plane d = np.dot(P-pp, n)/np.dot(pp-pn, n) ip = pp+(pp-pn)*d indexes[(pp_ind, pn_ind)] = (index, ip) index += 1 cell.append(indexes[(pp_ind, pn_ind)][0]) add_cell(cells, cell) MPI.barrier(mpi_comm_world()) # Assign global indices # TODO: Assign global indices properly dist = distribution(index) global_idx = sum(dist[:MPI.rank(mpi_comm_world())]) vertices = {} for idx, p in indexes.values(): vertices[idx] = (global_idx, p) global_idx += 1 global_num_cells = MPI.sum(mpi_comm_world(), len(cells)) global_num_vertices = MPI.sum(mpi_comm_world(), len(vertices)) mesh = Mesh() # Return empty mesh if no intersections were found if global_num_cells == 0: mesh_editor = MeshEditor() mesh_editor.open(mesh, "triangle", 2, 3) mesh_editor.init_vertices(0) mesh_editor.init_cells(0) mesh_editor.close() else: # Distribute mesh if empty on any processors cells, vertices = distribute_meshdata(cells, vertices) # Build mesh mesh_editor = MeshEditor() mesh_editor.open(mesh, "triangle", 2, 3) mesh_editor.init_vertices(len(vertices)) mesh_editor.init_cells(len(cells)) for index, cell in enumerate(cells): mesh_editor.add_cell(index, cell[0], cell[1], cell[2]) for local_index, (global_index, coordinates) in vertices.items(): mesh_editor.add_vertex_global(int(local_index), int(global_index), coordinates) mesh_editor.close() mesh.topology().init(0, len(vertices), global_num_vertices) mesh.topology().init(2, len(cells), global_num_cells) if closest_region and mesh.size_global(0) > 0: assert MPI.size(mpi_comm_world())==1, "Extract closest region does not work in parallel" regions = compute_connectivity(mesh) i,d = mesh.bounding_box_tree().compute_closest_entity(Point(P)) if d == MPI.min(mesh.mpi_comm(), d): v = regions[int(i)] else: v = 0 v = MPI.max(mesh.mpi_comm(), v) mesh = create_submesh(mesh, regions, v) return mesh
from fenicstools.observationoperator import TimeObsPtwise from fenicstools.objectiveacoustic import ObjectiveAcoustic from fenicstools.optimsolver import checkgradfd_med, checkhessabfd_med from fenicstools.prior import LaplacianPrior from fenicstools.jointregularization import V_TVPD, V_TV from fenicstools.mpicomm import create_communicators, partition_work from fenicstools.miscfenics import createMixedFS, ZeroRegularization, computecfromab from mediumparameters1 import \ targetmediumparameters, initmediumparameters, loadparameters dl.set_log_active(False) # Create local and global communicators mpicomm_local, mpicomm_global = create_communicators() mpiworldrank = MPI.rank(dl.mpi_comm_world()) PRINT = (mpiworldrank == 0) mpicommbarrier = dl.mpi_comm_world() # Command-line arguments try: k = float(sys.argv[1]) eps = float(sys.argv[2]) except: k = 7e-6 eps = 1e-3 ############## PARAM = 'ab' # shall not be changed TRANSMISSION = True NOISE = True
def mpi_is_root(): """ Check if current MPI node is root node. """ return MPI.rank(mpi_comm_world()) == 0
def distribute_meshdata(cells, vertices): """Because dolfin does not support a distributed mesh that is empty on some processes, we move a single cell from the process with the largest mesh to all processes with empty meshes.""" global_cell_distribution = distribution(len(cells)) x_per_v = 0 v_per_cell = 0 if len(vertices.values()) > 0: x_per_v = len(vertices.values()[0][1]) v_per_cell = len(cells[0]) x_per_v = int(MPI.max(mpi_comm_world(), x_per_v)) v_per_cell = int(MPI.max(mpi_comm_world(), v_per_cell)) # Move a single cell to process with no cells while 0 in global_cell_distribution: to_process = list(global_cell_distribution).index(0) from_process = list(global_cell_distribution).index( max(global_cell_distribution)) # Extract vertices and remove cells[0] on from_process v_out = np.zeros((1 + x_per_v) * v_per_cell) if MPI.rank(mpi_comm_world()) == from_process: # Structure v_out as (ind0, x0, y0, .., ind1, x1, .., ) for i, v in enumerate(cells[0]): v_out[i * (x_per_v + 1)] = vertices[v][0] v_out[i * (x_per_v + 1) + 1:(i + 1) * (x_per_v + 1)] = vertices[v][1] # Remove vertices no longer used in remaining cells. for i, v in enumerate(cells[0]): if not any([v in c for c in cells[1:]]): for j in xrange(len(cells)): cells[j] = [ vi - 1 if vi > v else vi for vi in cells[j] ] for vi in range(v, max(vertices)): vertices[vi] = vertices[vi + 1] vertices.pop(max(vertices)) cells.pop(0) MPI.barrier(mpi_comm_world()) # Broadcast vertices in cell[0] on from_process v_in = broadcast(v_out, from_process) MPI.barrier(mpi_comm_world()) # Create cell and vertices on to_process if MPI.rank(mpi_comm_world()) == to_process: for i in xrange(v_per_cell): vertices[i] = (int(v_in[i * (x_per_v + 1)]), v_in[i * (x_per_v + 1) + 1:(i + 1) * (x_per_v + 1)]) assert len(cells) == 0 cells = [range(v_per_cell)] MPI.barrier(mpi_comm_world()) # Update distribution global_cell_distribution = distribution(len(cells)) return cells, vertices
def on_master_process(): """Return True if on process number 0.""" return MPI.rank(mpi_comm_world()) == 0
# Create CG Krylov solver and turn convergence monitoring on solver = PETScKrylovSolver(MPI.comm_world) solver.set_from_options() # Set matrix operator solver.set_operator(A) # Compute solution solver.solve(u.vector(), b) # Save solution to XDMF format file = XDMFFile(MPI.comm_world, "elasticity.xdmf") file.write(u) unorm = u.vector().norm() if MPI.rank(mesh.mpi_comm()) == 0: print("Solution vector norm:", unorm) # Save colored mesh partitions in VTK format if running in parallel # if MPI.size(mesh.mpi_comm()) > 1: # File("partitions.pvd") << MeshFunction("size_t", mesh, mesh.topology.dim, \ # MPI.rank(mesh.mpi_comm())) # Project and write stress field to post-processing file # W = TensorFunctionSpace(mesh, "Discontinuous Lagrange", 0) # stress = project(sigma(u), V=W) # File("stress.pvd") << stress # Plot solution # import matplotlib.pyplot as plt # import dolfin.plotting
class iterative(block_base): def __init__(self, A, precond=1.0, tolerance=1e-5, initial_guess=None, iter=None, maxiter=200, name=None, show=1, rprecond=None, nonconvergence_is_fatal=False, retain_guess=False, relativeconv=False, callback=None, **kwargs): self.B = precond self.R = rprecond self.A = A self.initial_guess = initial_guess self.retain_guess = retain_guess self.nonconvergence_is_fatal = nonconvergence_is_fatal self.show = show self.callback = callback self.relativeconv = relativeconv self.kwargs = kwargs self.name = name if name else self.__class__.__name__ if iter is not None: tolerance = 0 maxiter = iter self.tolerance = tolerance self.maxiter = maxiter def create_vec(self, dim=1): return self.A.create_vec(dim) def matvec(self, b): from time import time from block.block_vec import block_vec from dolfin import log, info, Progress TRACE = 13 # dolfin.TRACE T = time() # If x and initial_guess are block_vecs, some of the blocks may be # scalars (although they are normally converted to vectors by bc # application). To be sure, call allocate() on them. if isinstance(b, block_vec): # Create a shallow copy to call allocate() on, to avoid changing the caller's copy of b b = block_vec(len(b), b.blocks) b.allocate(self.A, dim=0) if self.initial_guess: # Most (all?) solvers modify x, so make a copy to avoid changing # the caller's copy of x from block.block_util import copy x = copy(self.initial_guess) if isinstance(x, block_vec): x.allocate(self.A, dim=1) else: x = self.A.create_vec(dim=1) x.zero() try: log(TRACE, self.__class__.__name__+' solve of '+str(self.A)) if self.B != 1.0: log(TRACE, 'Using preconditioner: '+str(self.B)) progress = Progress(self.name, self.maxiter) if self.tolerance < 0: tolerance = -self.tolerance relative = True else: tolerance = self.tolerance relative = False x = self.method(self.B, self.AR, x, b, tolerance=tolerance, relativeconv=self.relativeconv, maxiter=self.maxiter, progress=progress, callback=self.callback, **self.kwargs) del progress # trigger final printout except Exception, e: from dolfin import warning warning("Error solving " + self.name) raise x, self.residuals, self.alphas, self.betas = x if self.tolerance == 0: msg = "done" elif self.converged: msg = "converged" else: msg = "NOT CONV." if self.show == 1: info('%s %s [iter=%2d, time=%.2fs, res=%.1e]' \ % (self.name, msg, self.iterations, time()-T, self.residuals[-1])) elif self.show >= 2: info('%s %s [iter=%2d, time=%.2fs, res=%.1e, true res=%.1e]' \ % (self.name, msg, self.iterations, time()-T, self.residuals[-1], (self.A*x-b).norm('l2'))) if self.show == 3: from dolfin import MPI if MPI.rank(None) == 0: try: from matplotlib import pyplot pyplot.figure('%s convergence (show=3)'%self.name) pyplot.semilogy(self.residuals) pyplot.show(block=True) except: pass if self.R is not None: x = self.R*x if self.retain_guess: self.initial_guess = x if not self.converged and self.nonconvergence_is_fatal: raise RuntimeError('Not converged') return x
bbox_inches='tight') from dolfin import list_timings, TimingType, TimingClear list_timings(TimingClear.keep, [TimingType.wall, TimingType.system]) t = list_timings(TimingClear.keep, [TimingType.wall, TimingType.user, TimingType.system]) # Use different MPI reductions # t_sum = MPI.sum(MPI.comm_world, t[0]) # t_min = MPI.min(MPI.comm_world, t[1]) # t_max = MPI.max(MPI.comm_world, t[2]) t_avg = MPI.avg(MPI.comm_world, t[3]) # Print aggregate timings to screen # print('\n'+t_sum.str(True)) # print('\n'+t_min.str(True)) # print('\n'+t_max.str(True)) print('\n' + t_avg.str(True)) # Store to XML file on rank 0 if MPI.rank(MPI.comm_world) == 0: f = File(MPI.comm_self, os.path.join(experiment, "timings_aggregate.xml")) # f << t_sum # f << t_min # f << t_max f << t_avg dump_timings_to_xml(os.path.join(experiment, "timings_avg_min_max.xml"), TimingClear.clear)
def mpi_rank(): return MPI.rank(mpi_comm())
def xtest_cffi_assembly(): mesh = UnitSquareMesh(MPI.comm_world, 13, 13) V = FunctionSpace(mesh, "Lagrange", 1) if MPI.rank(mesh.mpi_comm()) == 0: from cffi import FFI ffibuilder = FFI() ffibuilder.set_source( "_cffi_kernelA", r""" #include <math.h> #include <stdalign.h> void tabulate_tensor_poissonA(double* restrict A, const double* const* w, const double* restrict coordinate_dofs, int cell_orientation) { // Precomputed values of basis functions and precomputations // FE* dimensions: [entities][points][dofs] // PI* dimensions: [entities][dofs][dofs] or [entities][dofs] // PM* dimensions: [entities][dofs][dofs] alignas(32) static const double FE3_C0_D01_Q1[1][1][2] = { { { -1.0, 1.0 } } }; // Unstructured piecewise computations const double J_c0 = coordinate_dofs[0] * FE3_C0_D01_Q1[0][0][0] + coordinate_dofs[2] * FE3_C0_D01_Q1[0][0][1]; const double J_c3 = coordinate_dofs[1] * FE3_C0_D01_Q1[0][0][0] + coordinate_dofs[5] * FE3_C0_D01_Q1[0][0][1]; const double J_c1 = coordinate_dofs[0] * FE3_C0_D01_Q1[0][0][0] + coordinate_dofs[4] * FE3_C0_D01_Q1[0][0][1]; const double J_c2 = coordinate_dofs[1] * FE3_C0_D01_Q1[0][0][0] + coordinate_dofs[3] * FE3_C0_D01_Q1[0][0][1]; alignas(32) double sp[20]; sp[0] = J_c0 * J_c3; sp[1] = J_c1 * J_c2; sp[2] = sp[0] + -1 * sp[1]; sp[3] = J_c0 / sp[2]; sp[4] = -1 * J_c1 / sp[2]; sp[5] = sp[3] * sp[3]; sp[6] = sp[3] * sp[4]; sp[7] = sp[4] * sp[4]; sp[8] = J_c3 / sp[2]; sp[9] = -1 * J_c2 / sp[2]; sp[10] = sp[9] * sp[9]; sp[11] = sp[8] * sp[9]; sp[12] = sp[8] * sp[8]; sp[13] = sp[5] + sp[10]; sp[14] = sp[6] + sp[11]; sp[15] = sp[12] + sp[7]; sp[16] = fabs(sp[2]); sp[17] = sp[13] * sp[16]; sp[18] = sp[14] * sp[16]; sp[19] = sp[15] * sp[16]; // UFLACS block mode: preintegrated A[0] = 0.5 * sp[19] + 0.5 * sp[18] + 0.5 * sp[18] + 0.5 * sp[17]; A[1] = -0.5 * sp[19] + -0.5 * sp[18]; A[2] = -0.5 * sp[18] + -0.5 * sp[17]; A[3] = -0.5 * sp[19] + -0.5 * sp[18]; A[4] = 0.5 * sp[19]; A[5] = 0.5 * sp[18]; A[6] = -0.5 * sp[18] + -0.5 * sp[17]; A[7] = 0.5 * sp[18]; A[8] = 0.5 * sp[17]; } void tabulate_tensor_poissonL(double* restrict A, const double* const* w, const double* restrict coordinate_dofs, int cell_orientation) { // Precomputed values of basis functions and precomputations // FE* dimensions: [entities][points][dofs] // PI* dimensions: [entities][dofs][dofs] or [entities][dofs] // PM* dimensions: [entities][dofs][dofs] alignas(32) static const double FE4_C0_D01_Q1[1][1][2] = { { { -1.0, 1.0 } } }; // Unstructured piecewise computations const double J_c0 = coordinate_dofs[0] * FE4_C0_D01_Q1[0][0][0] + coordinate_dofs[2] * FE4_C0_D01_Q1[0][0][1]; const double J_c3 = coordinate_dofs[1] * FE4_C0_D01_Q1[0][0][0] + coordinate_dofs[5] * FE4_C0_D01_Q1[0][0][1]; const double J_c1 = coordinate_dofs[0] * FE4_C0_D01_Q1[0][0][0] + coordinate_dofs[4] * FE4_C0_D01_Q1[0][0][1]; const double J_c2 = coordinate_dofs[1] * FE4_C0_D01_Q1[0][0][0] + coordinate_dofs[3] * FE4_C0_D01_Q1[0][0][1]; alignas(32) double sp[4]; sp[0] = J_c0 * J_c3; sp[1] = J_c1 * J_c2; sp[2] = sp[0] + -1 * sp[1]; sp[3] = fabs(sp[2]); // UFLACS block mode: preintegrated A[0] = 0.1666666666666667 * sp[3]; A[1] = 0.1666666666666667 * sp[3]; A[2] = 0.1666666666666667 * sp[3]; } """) ffibuilder.cdef(""" void tabulate_tensor_poissonA(double* restrict A, const double* const* w, const double* restrict coordinate_dofs, int cell_orientation); void tabulate_tensor_poissonL(double* restrict A, const double* const* w, const double* restrict coordinate_dofs, int cell_orientation); """) ffibuilder.compile(verbose=True) MPI.barrier(mesh.mpi_comm()) from _cffi_kernelA import ffi, lib a = cpp.fem.Form([V._cpp_object, V._cpp_object]) ptrA = ffi.cast("intptr_t", ffi.addressof(lib, "tabulate_tensor_poissonA")) a.set_cell_tabulate(0, ptrA) L = cpp.fem.Form([V._cpp_object]) ptrL = ffi.cast("intptr_t", ffi.addressof(lib, "tabulate_tensor_poissonL")) L.set_cell_tabulate(0, ptrL) assembler = cpp.fem.Assembler([[a]], [L], []) A = assembler.assemble_matrix(cpp.fem.Assembler.BlockType.monolithic) b = assembler.assemble_vector(cpp.fem.Assembler.BlockType.monolithic) Anorm = A.norm(cpp.la.Norm.frobenius) bnorm = b.norm(cpp.la.Norm.l2) assert (np.isclose(Anorm, 56.124860801609124)) assert (np.isclose(bnorm, 0.0739710713711999)) list_timings([TimingType.wall])
def test_cost(eps_in, k_in): mesh = UnitSquareMesh(10, 10) param = {'eps': eps_in, 'k': k_in} NN = NuclearNormSVD2D(mesh, param) NN2 = NuclearNormformula(mesh, param) test = 0 mpicomm = mesh.mpi_comm() mpirank = MPI.rank(mpicomm) if mpirank == 0: print '-------------------------------------' print 'Test cost functional. eps={}'.format(eps_in) print '-------------------------------------' test += 1 if mpirank == 0: print 'Test {}: (0,0)'.format(test) m1 = Function(NN.V) m2 = Function(NN.V) nn = NN.costab(m1, m2) nn2 = NN2.costab(m1, m2) tt = 2.0 * np.sqrt(eps_in) * k_in if mpirank == 0: print 'cost={}, err={:.2e}'.format(nn, np.abs(nn - tt) / tt) print 'cost2={}, err={:.2e}'.format(nn2, np.abs(nn2 - tt) / tt) test += 1 if mpirank == 0: print 'Test {}: (x,y)'.format(test) m1 = interpolate(Expression("x[0]", degree=10), NN.V) m2 = interpolate(Expression("x[1]", degree=10), NN.V) nn = NN.costab(m1, m2) nn2 = NN2.costab(m1, m2) tt = 2.0 * np.sqrt(1.0 + eps_in) * k_in if mpirank == 0: print 'cost={}, err={:.2e}'.format(nn, np.abs(nn - tt) / tt) print 'cost2={}, err={:.2e}'.format(nn2, np.abs(nn2 - tt) / tt) test += 1 if mpirank == 0: print 'Test {}: (x^2, y^2)'.format(test) m1 = interpolate(Expression("x[0]*x[0]", degree=10), NN.V) m2 = interpolate(Expression("x[1]*x[1]", degree=10), NN.V) nn = NN.costab(m1, m2) nn2 = NN2.costab(m1, m2) tt = 2.0 * k_in # only true for eps=0 if mpirank == 0: print 'cost={}, err={:.2e}'.format(nn, np.abs(nn - tt) / tt) print 'cost2={}, err={:.2e}'.format(nn2, np.abs(nn2 - tt) / tt) test += 1 if mpirank == 0: print 'Test {}: (x+y, x+y)'.format(test) m1 = interpolate(Expression("x[0] + x[1]", degree=10), NN.V) m2 = interpolate(Expression("x[0] + x[1]", degree=10), NN.V) nn = NN.costab(m1, m2) nn2 = NN2.costab(m1, m2) tt = (np.sqrt(2.0 * 2.0 + eps_in) + np.sqrt(eps_in)) * k_in if mpirank == 0: print 'cost={}, err={:.2e}'.format(nn, np.abs(nn - tt) / tt) print 'cost2={}, err={:.2e}'.format(nn2, np.abs(nn2 - tt) / tt) test += 1 if mpirank == 0: print 'Test {}: (x+y, x-y)'.format(test) m1 = interpolate(Expression("x[0] + x[1]", degree=10), NN.V) m2 = interpolate(Expression("x[0] - x[1]", degree=10), NN.V) nn = NN.costab(m1, m2) nn2 = NN2.costab(m1, m2) tt = 2.0 * np.sqrt(2.0 + eps) * k_in if mpirank == 0: print 'cost={}, err={:.2e}'.format(nn, np.abs(nn - tt) / tt) print 'cost2={}, err={:.2e}'.format(nn2, np.abs(nn2 - tt) / tt) test += 1 if mpirank == 0: print 'Test {}: (x^2+y, x+y^2)'.format(test) m1 = interpolate(Expression("x[0]*x[0] + x[1]", degree=10), NN.V) m2 = interpolate(Expression("x[0] + x[1]*x[1]", degree=10), NN.V) nn = NN.costab(m1, m2) nn2 = NN2.costab(m1, m2) if mpirank == 0: print 'cost={}, cost2={}, diff={:.2e}'.format( nn, nn2, np.abs(nn - nn2) / np.abs(nn2)) test += 1 if mpirank == 0: print 'Test {}: (x^2*y, x*y^2)'.format(test) m1 = interpolate(Expression("x[0]*x[0]*x[1]", degree=10), NN.V) m2 = interpolate(Expression("x[0]*x[1]*x[1]", degree=10), NN.V) nn = NN.costab(m1, m2) nn2 = NN2.costab(m1, m2) if mpirank == 0: print 'cost={}, cost2={}, diff={:.2e}'.format( nn, nn2, np.abs(nn - nn2) / np.abs(nn2)) test += 1 if mpirank == 0: print 'Test {}: coincide'.format(test) m1 = interpolate(Expression('log(10 - ' + \ '(pow(pow(x[0]-0.5,2)+pow(x[1]-0.5,2),0.5)<0.4) * (' + \ '4*(x[0]<=0.5) + 8*(x[0]>0.5) ))', degree=10), NN.V) m2 = interpolate(Expression('log(10 - ' + \ '(pow(pow(x[0]-0.5,2)+pow(x[1]-0.5,2),0.5)<0.4) * (' + \ '8*(x[0]<=0.5) + 4*(x[0]>0.5) ))', degree=10), NN.V) nn = NN.costab(m1, m2) nn2 = NN2.costab(m1, m2) if mpirank == 0: print 'cost={}, cost2={}, diff={:.2e}'.format( nn, nn2, np.abs(nn - nn2) / np.abs(nn2)) test += 1 if mpirank == 0: print 'Test {}: coincide2'.format(test) m1 = interpolate(Expression('log(10 - ' + \ '(pow(pow(x[0]-0.5,2)+pow(x[1]-0.5,2),0.5)<0.4) * 8 )', degree=10), NN.V) m2 = interpolate(Expression('log(10 - ' + \ '(pow(pow(x[0]-0.5,2)+pow(x[1]-0.5,2),0.5)<0.4) * (' + \ '8*(x[0]<=0.5) + 4*(x[0]>0.5) ))', degree=10), NN.V) nn = NN.costab(m1, m2) nn2 = NN2.costab(m1, m2) if mpirank == 0: print 'cost={}, cost2={}, diff={:.2e}'.format( nn, nn2, np.abs(nn - nn2) / np.abs(nn2))
def inversion(self, initial_medium, target_medium, mpicomm, \ parameters_in=[], myplot=None): """ solve inverse problem with that objective function """ parameters = {'tolgrad':1e-10, 'tolcost':1e-14, 'maxnbNewtiter':50, \ 'maxtolcg':0.5} parameters.update(parameters_in) maxnbNewtiter = parameters['maxnbNewtiter'] tolgrad = parameters['tolgrad'] tolcost = parameters['tolcost'] tolcg = parameters['maxtolcg'] mpirank = MPI.rank(mpicomm) self.update_m(initial_medium) self._plotm(myplot, 'init') if mpirank == 0: print '\t{:12s} {:10s} {:12s} {:12s} {:12s} {:10s} \t{:10s} {:12s} {:12s}'.format(\ 'iter', 'cost', 'misfit', 'reg', '|G|', 'medmisf', 'a_ls', 'tol_cg', 'n_cg') dtruenorm = np.sqrt(target_medium.vector().\ inner(self.MM*target_medium.vector())) self.solvefwd_cost() for it in xrange(maxnbNewtiter): self.solveadj_constructgrad() # compute gradient if it == 0: gradnorm0 = self.Gradnorm diff = self.m.vector() - target_medium.vector() medmisfit = np.sqrt(diff.inner(self.MM * diff)) if mpirank == 0: print '{:12d} {:12.4e} {:12.2e} {:12.2e} {:11.4e} {:10.2e} ({:4.2f})'.\ format(it, self.cost, self.misfit, self.regul, \ self.Gradnorm, medmisfit, medmisfit/dtruenorm), self._plotm(myplot, str(it)) self._plotgrad(myplot, str(it)) if self.Gradnorm < gradnorm0 * tolgrad or self.Gradnorm < 1e-12: if mpirank == 0: print '\nGradient sufficiently reduced -- optimization stopped' break # Compute search direction: tolcg = min(tolcg, np.sqrt(self.Gradnorm / gradnorm0)) self.assemble_hessian() # for regularization cgiter, cgres, cgid, tolcg = compute_searchdirection( self, 'Newt', tolcg) self._plotsrchdir(myplot, str(it)) # Line search: cost_old = self.cost statusLS, LScount, alpha = bcktrcklinesearch(self, 12) if mpirank == 0: print '{:11.3f} {:12.2e} {:10d}'.format(alpha, tolcg, cgiter) if self.PD: self.Regul.update_w(self.srchdir.vector(), alpha) if np.abs(self.cost - cost_old) / np.abs(cost_old) < tolcost: if mpirank == 0: if tolcg < 1e-14: print 'Cost function stagnates -- optimization aborted' break tolcg = 0.001 * tolcg
def restriction_map(V, Vb, _all_coords=None, _all_coordsb=None): "Return a map between dofs in Vb to dofs in V. Vb's mesh should be a submesh of V's Mesh." if V.ufl_element().family( ) == "Discontinuous Lagrange" and V.ufl_element().degree() > 0: raise RuntimeError( "This function does not work for DG-spaces of degree >0 \ (several dofs associated with same point in same subspace)." ) if V.ufl_element().family() != "Lagrange": cbc_warning("This function is only tested for CG-spaces.") assert V.ufl_element().family() == Vb.ufl_element().family( ), "ufl elements differ in the two spaces" assert V.ufl_element().degree() == Vb.ufl_element().degree( ), "ufl elements differ in the two spaces" assert V.ufl_element().cell() == Vb.ufl_element().cell( ), "ufl elements differ in the two spaces" D = V.mesh().geometry().dim() # Recursively call this function if V has sub-spaces if V.num_sub_spaces() > 0: mapping = {} if MPI.size(mpi_comm_world()) == 1: if _all_coords is None: try: # For 1.6.0+ and newer all_coords = V.tabulate_dof_coordinates().reshape( V.dim(), D) all_coordsb = Vb.tabulate_dof_coordinates().reshape( Vb.dim(), D) except: # For 1.6.0 and older all_coords = V.dofmap().tabulate_all_coordinates( V.mesh()).reshape(V.dim(), D) all_coordsb = Vb.dofmap().tabulate_all_coordinates( Vb.mesh()).reshape(Vb.dim(), D) else: all_coords = _all_coords all_coordsb = _all_coordsb else: all_coords = None all_coordsb = None for i in range(V.num_sub_spaces()): mapping.update( restriction_map(V.sub(i), Vb.sub(i), all_coords, all_coordsb)) return mapping dm = V.dofmap() dmb = Vb.dofmap() N = len(dm.dofs()) Nb = len(dmb.dofs()) dofs = dm.dofs() # Extract coordinates of dofs if dm.is_view(): if _all_coords is not None: coords = _all_coords[V.dofmap().dofs()] else: try: # For 1.6.0+ and newer coords = V.collapse().tabulate_dof_coordinates().reshape(N, D) except: # For 1.6.0 and older coords = V.collapse().dofmap().tabulate_all_coordinates( V.mesh()).reshape(N, D) if _all_coordsb is not None: coordsb = _all_coordsb[Vb.dofmap().dofs()] else: try: # For 1.6.0+ and newer coordsb = Vb.collapse().tabulate_dof_coordinates().reshape( Nb, D) except: # For 1.6.0 and older coordsb = Vb.collapse().dofmap().tabulate_all_coordinates( Vb.mesh()).reshape(Nb, D) else: if LooseVersion(dolfin_version()) > LooseVersion("1.6.0"): # For 1.6.0+ and newer coords = V.tabulate_dof_coordinates().reshape(N, D) coordsb = Vb.tabulate_dof_coordinates().reshape(Nb, D) else: # For 1.6.0 and older coords = V.dofmap().tabulate_all_coordinates(V.mesh()).reshape( N, D) coordsb = Vb.dofmap().tabulate_all_coordinates(Vb.mesh()).reshape( Nb, D) # Build KDTree to compute distances from coordinates in base kdtree = KDTree(coords) eps = 1e-12 mapping = {} request_dofs = np.array([]) distances, indices = kdtree.query(coordsb) for i, subdof in enumerate(dmb.dofs()): # Find closest dof in base #d, idx = kdtree.query(coordsb[i]) d, idx = distances[i], indices[i] if d < eps: # Dof found on this process, add to map dof = dofs[idx] assert subdof not in mapping mapping[subdof] = dof else: # Search for this dof on other processes add_dofs = np.hstack(([subdof], coordsb[i])) request_dofs = np.append(request_dofs, add_dofs) del distances del indices # Scatter all dofs not found on current process to all processes all_request_dofs = [None] * MPI.size(mpi_comm_world()) for j in xrange(MPI.size(mpi_comm_world())): all_request_dofs[j] = broadcast(request_dofs, j) # Re-order all requested dofs # Remove items coming from this process all_request_dofs[MPI.rank(mpi_comm_world())] = [] all_request_dofs = np.hstack(all_request_dofs) all_request_dofs = all_request_dofs.reshape( len(all_request_dofs) / (D + 1), D + 1) all_request_dofs = dict( zip(all_request_dofs[:, 0], all_request_dofs[:, 1:])) # Search this process for all dofs not found on same process as subdof for subdof, coordsbi in all_request_dofs.items(): subdof = int(subdof) # Find closest dof in base d, idx = kdtree.query(coordsbi) if d < eps: # Dof found on this process, add to map dof = dofs[idx] assert subdof not in mapping mapping[subdof] = dof return mapping
def test_grad(eps_in, k_in): mesh = UnitSquareMesh(10, 10) param = {'eps': eps_in, 'k': k_in} NN = NuclearNormSVD2D(mesh, param) NN2 = NuclearNormformula(mesh, param) direc12 = Function(NN.VV) m1h, m2h = Function(NN.V), Function(NN.V) H = [1e-4, 1e-5, 1e-6, 1e-7] mpicomm = mesh.mpi_comm() mpirank = MPI.rank(mpicomm) mpisize = MPI.size(mpicomm) if mpirank == 0: print '-------------------------------------' print 'Test gradient. eps={}'.format(eps) print '-------------------------------------' if mpirank == 0: print 'Test 1' m1 = Function(NN.V) m2 = Function(NN.V) grad = NN.gradab(m1, m2) grad2 = NN2.gradab(m1, m2) normgrad = norm(grad) normgrad2 = norm(grad2) if mpirank == 0: print '|grad|={}, err={}'.format(normgrad, np.abs(normgrad)) print '|grad2|={}, err={}'.format(normgrad2, np.abs(normgrad2)) M1 = [interpolate(Expression("x[0] + x[1]", degree=10), NN.V), interpolate(Expression("x[0] * x[1]", degree=10), NN.V), interpolate(Expression("x[0]*x[0] + x[1]", degree=10), NN.V), interpolate(Expression('log(10 - ' + \ '(pow(pow(x[0]-0.5,2)+pow(x[1]-0.5,2),0.5)<0.4) * (' + \ '4*(x[0]<=0.5) + 8*(x[0]>0.5) ))', degree=10), NN.V), interpolate(Expression('log(10 - ' + \ '(pow(pow(x[0]-0.5,2)+pow(x[1]-0.5,2),0.5)<0.4) * 8 )', degree=10), NN.V)] M2 = [interpolate(Expression("x[0] + x[1]", degree=10), NN.V), interpolate(Expression("1.0 + cos(x[0])", degree=10), NN.V), interpolate(Expression("x[1]*x[1] + x[0]", degree=10), NN.V), interpolate(Expression('log(10 - ' + \ '(pow(pow(x[0]-0.5,2)+pow(x[1]-0.5,2),0.5)<0.4) * (' + \ '8*(x[0]<=0.5) + 4*(x[0]>0.5) ))', degree=10), NN.V), interpolate(Expression('log(10 - ' + \ '(pow(pow(x[0]-0.5,2)+pow(x[1]-0.5,2),0.5)<0.4) * (' + \ '8*(x[0]<=0.5) + 4*(x[0]>0.5) ))', degree=10), NN.V)] tt = 2 for m1, m2 in zip(M1, M2): if mpirank == 0: print '\nTest {}'.format(tt) tt += 1 grad = NN.gradab(m1, m2) grad2 = NN2.gradab(m1, m2) for nn in range(5): if mpirank == 0: print '--direction {}'.format(nn) direc1 = interpolate(Expression('1 + sin(n*pi*x[0])*sin(n*pi*x[1])',\ n=nn, degree=10), NN.V) direc2 = interpolate(Expression('1 + cos(n*pi*x[0])*cos(n*pi*x[1])',\ n=nn, degree=10), NN.V) assign(direc12.sub(0), direc1) assign(direc12.sub(1), direc2) direcderiv = grad.inner(direc12.vector()) direcderiv2 = grad2.inner(direc12.vector()) if mpirank == 0: print 'grad={}, '.format(direcderiv) print 'grad2={}, diff={:.2e} '.format(direcderiv2, \ np.abs(direcderiv-direcderiv2)/np.abs(direcderiv)) for hh in H: setfct(m1h, m1) m1h.vector().axpy(hh, direc1.vector()) setfct(m2h, m2) m2h.vector().axpy(hh, direc2.vector()) cost1 = NN.costab(m1h, m2h) setfct(m1h, m1) m1h.vector().axpy(-hh, direc1.vector()) setfct(m2h, m2) m2h.vector().axpy(-hh, direc2.vector()) cost2 = NN.costab(m1h, m2h) FDdirecderiv = (cost1 - cost2) / (2.0 * hh) if np.abs(direcderiv) > 1e-16: err = np.abs(direcderiv - FDdirecderiv) / np.abs(direcderiv) else: err = np.abs(direcderiv - FDdirecderiv) if mpirank == 0: print '\th={}, fd={}, err={:.2e}'.format( hh, FDdirecderiv, err), if err < 1e-6: if mpirank == 0: print '\t =>> OK!' break else: if mpirank == 0: print ''
subdomains.mark(cell_domains, 1) if MPI.size(mpi_comm_world()) == 1: submesh = SubMesh(mesh, cell_domains, 1) else: submesh = create_submesh(mesh, cell_domains, 1) #MPI.barrier(mpi_comm_world()) #continue V = FunctionSpace(submesh, "CG", 2) expr = Expression("x[0]*x[1]*x[1]+4*x[2]", degree=2) u = project(expr, V) MPI.barrier(mpi_comm_world()) s0 = submesh.size_global(0) s3 = submesh.size_global(submesh.ufl_cell().topological_dimension()) a = assemble(u * dx) v = assemble(Constant(1) * dx(domain=submesh)) if MPI.rank(mpi_comm_world()) == 0: print("Num vertices: ", s0) print("Num cells: ", s3) print("assemble(u*dx): ", a) print("Volume: ", v) #u = Function(V) #File("u.pvd") << u #import ipdb; ipdb.set_trace() #print mesh.num_cells() #print dir(mesh) #print mesh.cells()
def create_submesh(mesh, markers, marker): "This function allows for a SubMesh-equivalent to be created in parallel" # Build mesh submesh = Mesh() mesh_editor = MeshEditor() mesh_editor.open(submesh, mesh.ufl_cell().cellname(), mesh.ufl_cell().topological_dimension(), mesh.ufl_cell().geometric_dimension()) # Return empty mesh if no matching markers if MPI.sum(mpi_comm_world(), int(marker in markers.array())) == 0: cbc_warning( "Unable to find matching markers in meshfunction. Submesh is empty." ) mesh_editor.close() return submesh base_cell_indices = np.where(markers.array() == marker)[0] base_cells = mesh.cells()[base_cell_indices] base_vertex_indices = np.unique(base_cells.flatten()) base_global_vertex_indices = sorted( [mesh.topology().global_indices(0)[vi] for vi in base_vertex_indices]) gi = mesh.topology().global_indices(0) shared_local_indices = set(base_vertex_indices).intersection( set(mesh.topology().shared_entities(0).keys())) shared_global_indices = [gi[vi] for vi in shared_local_indices] unshared_global_indices = list( set(base_global_vertex_indices) - set(shared_global_indices)) unshared_vertices_dist = distribution(len(unshared_global_indices)) # Number unshared vertices on separate process idx = sum(unshared_vertices_dist[:MPI.rank(mpi_comm_world())]) base_to_sub_global_indices = {} for gi in unshared_global_indices: base_to_sub_global_indices[gi] = idx idx += 1 # Gather all shared process on process 0 and assign global index all_shared_global_indices = gather(shared_global_indices, on_process=0, flatten=True) all_shared_global_indices = np.unique(all_shared_global_indices) shared_base_to_sub_global_indices = {} idx = int( MPI.max(mpi_comm_world(), float(max(base_to_sub_global_indices.values() + [-1e16]))) + 1) if MPI.rank(mpi_comm_world()) == 0: for gi in all_shared_global_indices: shared_base_to_sub_global_indices[int(gi)] = idx idx += 1 # Broadcast global numbering of all shared vertices shared_base_to_sub_global_indices = dict( zip(broadcast(shared_base_to_sub_global_indices.keys(), 0), broadcast(shared_base_to_sub_global_indices.values(), 0))) # Join shared and unshared numbering in one dict base_to_sub_global_indices = dict( base_to_sub_global_indices.items() + shared_base_to_sub_global_indices.items()) # Create mapping of local indices base_to_sub_local_indices = dict( zip(base_vertex_indices, range(len(base_vertex_indices)))) # Define sub-cells sub_cells = [None] * len(base_cells) for i, c in enumerate(base_cells): sub_cells[i] = [base_to_sub_local_indices[j] for j in c] # Store vertices as sub_vertices[local_index] = (global_index, coordinates) sub_vertices = {} for base_local, sub_local in base_to_sub_local_indices.items(): sub_vertices[sub_local] = (base_to_sub_global_indices[ mesh.topology().global_indices(0)[base_local]], mesh.coordinates()[base_local]) ## Done with base mesh # Distribute meshdata on (if any) empty processes sub_cells, sub_vertices = distribute_meshdata(sub_cells, sub_vertices) global_cell_distribution = distribution(len(sub_cells)) #global_vertex_distribution = distribution(len(sub_vertices)) global_num_cells = MPI.sum(mpi_comm_world(), len(sub_cells)) global_num_vertices = sum(unshared_vertices_dist) + MPI.sum( mpi_comm_world(), len(all_shared_global_indices)) mesh_editor.init_vertices(len(sub_vertices)) #mesh_editor.init_cells(len(sub_cells)) mesh_editor.init_cells_global(len(sub_cells), global_num_cells) global_index_start = sum( global_cell_distribution[:MPI.rank(mesh.mpi_comm())]) for index, cell in enumerate(sub_cells): if LooseVersion(dolfin_version()) >= LooseVersion("1.6.0"): mesh_editor.add_cell(index, *cell) else: mesh_editor.add_cell(int(index), global_index_start + index, np.array(cell, dtype=np.uintp)) for local_index, (global_index, coordinates) in sub_vertices.items(): #print coordinates mesh_editor.add_vertex_global(int(local_index), int(global_index), coordinates) mesh_editor.close() submesh.topology().init(0, len(sub_vertices), global_num_vertices) submesh.topology().init(mesh.ufl_cell().topological_dimension(), len(sub_cells), global_num_cells) # FIXME: Set up shared entities # What damage does this do? submesh.topology().shared_entities(0)[0] = [] # The code below sets up shared vertices, but lacks shared facets. # It is considered incomplete, and therefore commented out ''' #submesh.topology().shared_entities(0)[0] = [] from dolfin import compile_extension_module cpp_code = """ void set_shared_entities(Mesh& mesh, std::size_t idx, const Array<std::size_t>& other_processes) { std::set<unsigned int> set_other_processes; for (std::size_t i=0; i<other_processes.size(); i++) { set_other_processes.insert(other_processes[i]); //std::cout << idx << " --> " << other_processes[i] << std::endl; } //std::cout << idx << " --> " << set_other_processes[0] << std::endl; mesh.topology().shared_entities(0)[idx] = set_other_processes; } """ set_shared_entities = compile_extension_module(cpp_code).set_shared_entities base_se = mesh.topology().shared_entities(0) se = submesh.topology().shared_entities(0) for li in shared_local_indices: arr = np.array(base_se[li], dtype=np.uintp) sub_li = base_to_sub_local_indices[li] set_shared_entities(submesh, base_to_sub_local_indices[li], arr) ''' return submesh
def create_folders(folder, sub_folder, restart_folder, **namespace): """Manage paths for where to store the checkpoint and visualizations""" if restart_folder is None: # Get path to sub folder for this simulation path = Path.cwd() / folder if sub_folder is not None: path = path.joinpath(sub_folder) else: if not [ int(str(i.name)) for i in path.glob("*") if str(i.name).isdigit() ]: path = path.joinpath("1") else: number = max([ int(str(i.name)) for i in path.glob("*") if str(i.name).isdigit() ]) path = path.joinpath(str(number + 1)) else: path = restart_folder MPI.barrier(MPI.comm_world) if not path.joinpath("Checkpoint").exists() and restart_folder is not None: raise NotADirectoryError(( "The restart folder: {} does not have a sub folder 'Checkpoint' where we can" " restart the simulation from.").format(restart_folder)) # Folders for visualization and checkpointing checkpoint_folder = path.joinpath("Checkpoint") visualization_folder = path.joinpath("Visualization") # Check if there exists previous visualization files, if so move and change name if list(visualization_folder.glob("*")) != []: # Get number of run a = list(visualization_folder.glob("velocity*.h5")) b = [ int(i.__str__().split("_")[-1].split(".")[0]) for i in a if "_" in i.name.__str__() ] run_number = 1 if len(b) == 0 else max(b) + 1 for name in ["displacement", "velocity", "pressure"]: for suffix in [".h5", ".xdmf"]: new_name = visualization_folder.joinpath(name + "_run_" + str(run_number) + suffix) tmp_path = visualization_folder.joinpath(name + suffix) tmp_path.rename(new_name) # Rename link in xdmf file with open(new_name) as f: text = f.read().replace( name + ".h5", new_name.name.__str__().replace(".xdmf", ".h5")) with open(new_name, "w") as f: f.write(text) else: run_number = 0 if MPI.rank(MPI.comm_world) == 0: checkpoint_folder.mkdir(parents=True, exist_ok=True) visualization_folder.mkdir(parents=True, exist_ok=True) return dict(checkpoint_folder=checkpoint_folder, visualization_folder=visualization_folder, results_folder=path, run_number=run_number)
def numerical_test( user_parameters, ell=0.05, nu=0., ): time_data = [] time_data_pd = [] spacetime = [] lmbda_min_prev = 1e-6 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurc_i = 0 bifurcation_loads = [] # Create mesh and define function space # geometry_parameters = {'R': 1., 'n': 5} # Define Dirichlet boundaries comm = MPI.comm_world with open('../parameters/form_compiler.yml') as f: form_compiler_parameters = yaml.load(f, Loader=yaml.FullLoader) with open('../parameters/solvers_default.yml') as f: solver_parameters = yaml.load(f, Loader=yaml.FullLoader) with open('../parameters/solvers_default.yml') as f: damage_parameters = yaml.load(f, Loader=yaml.FullLoader)['damage'] with open('../parameters/solvers_default.yml') as f: elasticity_parameters = yaml.load(f, Loader=yaml.FullLoader)['elasticity'] with open('../parameters/film.yaml') as f: material_parameters = yaml.load(f, Loader=yaml.FullLoader)['material'] with open('../parameters/loading.yaml') as f: loading_parameters = yaml.load(f, Loader=yaml.FullLoader)['loading'] with open('../parameters/stability.yaml') as f: stability_parameters = yaml.load(f, Loader=yaml.FullLoader)['stability'] with open('../parameters/stability.yaml') as f: inertia_parameters = yaml.load(f, Loader=yaml.FullLoader)['inertia'] with open('../parameters/stability.yaml') as f: eigen_parameters = yaml.load(f, Loader=yaml.FullLoader)['eigen'] # import pdb; pdb.set_trace() default_parameters = { 'code': { **code_parameters }, 'compiler': { **form_compiler_parameters }, 'eigen': { **eigen_parameters }, # 'geometry': {**geometry_parameters}, 'inertia': { **inertia_parameters }, 'loading': { **loading_parameters }, 'material': { **material_parameters }, 'solver': { **solver_parameters }, 'stability': { **stability_parameters }, 'elasticity': { **elasticity_parameters }, 'damage': { **damage_parameters }, } default_parameters.update(user_parameters) # FIXME: Not nice parameters = default_parameters signature = hashlib.md5(str(parameters).encode('utf-8')).hexdigest() outdir = '../test/output/film2d/{}'.format(signature) # outdir = '../test/output/test_film2d-init-{}'.format(signature) Path(outdir).mkdir(parents=True, exist_ok=True) log(LogLevel.INFO, 'INFO: Outdir is: ' + outdir) R = parameters['geometry']['R'] # Mesh1 ================================== # geom = mshr.Circle(dolfin.Point(0., 0.), R) # resolution = max(geometry_parameters['n'] * Lx / ell, 1/(Ly*10)) # resolution = max(parameters['geometry']['n'] * R / ell, (10/R)) # resolution = 10 # log(LogLevel.INFO, 'mesh resolution {}'.format(resolution)) # mesh = mshr.generate_mesh(geom, resolution) # Mesh2 ================================== # mesh = dolfin.Mesh("../scripts/meshes/diskR3-mesh.xml") # Mesh3 ================================== # fname = os.path.join('../meshes', 'circle-init-{}'.format(geom_signature)) d = { 'rad': parameters['geometry']['R'], 'h': parameters['material']['ell'] / parameters['geometry']['n'] } geom_signature = hashlib.md5(str(d).encode('utf-8')).hexdigest() fname = os.path.join('../meshes', 'circle-{}'.format(geom_signature)) if os.path.isfile(fname + '.xml'): log(LogLevel.INFO, "Meshfile {} exists".format(fname)) mesh = dolfin.Mesh("{}.xml".format(fname)) else: log(LogLevel.INFO, "Creating meshfile: %s" % fname) log(LogLevel.INFO, "DEBUG: parameters: %s" % d) # mesh_template = open('../scripts/templates/circle_template_init.geo') if MPI.rank(MPI.comm_world) == 0: mesh_template = open('../scripts/templates/circle_template.geo') src = Template(mesh_template.read()) geofile = src.substitute(d) with open(fname + ".geo", 'w') as f: f.write(geofile) cmd1 = 'gmsh {}.geo -2 -o {}.msh'.format(fname, fname) cmd2 = 'dolfin-convert -i gmsh {}.msh {}.xml'.format(fname, fname) log( LogLevel.INFO, 'Unable to handle mesh generation at the moment, please generate the mesh and test again.' ) log(LogLevel.INFO, cmd1) log(LogLevel.INFO, cmd2) sys.exit() log(LogLevel.INFO, check_output([cmd1], shell=True) ) # run in shell mode in case you are not run in terminal Popen([cmd2], stdout=PIPE, shell=True).communicate() mesh = Mesh('{}.xml'.format(fname)) mesh_xdmf = XDMFFile("{}.xdmf".format(fname)) mesh_xdmf.write(mesh) log(LogLevel.INFO, fname) # boundary_meshfunction = dolfin.MeshFunction("size_t", mesh, "{}_facet_region.xml".format(fname)) # cells_meshfunction = dolfin.MeshFunction("size_t", mesh, "{}_physical_region.xml".format(fname)) # mesh_xdmf = dolfin.XDMFFile("meshes/%s-%s.xdmf"%(fname, geom_signature)) # mesh_xdmf.write(mesh) # if rank == 0: # meshf = dolfin.File(os.path.join(outdir, "mesh.xml")) # meshf << mesh log(LogLevel.WARNING, 'porcoilclero') if size == 1: meshf = dolfin.File(os.path.join(outdir, "mesh.xml")) meshf << mesh plot(mesh) plt.savefig(os.path.join(outdir, "mesh.pdf"), bbox_inches='tight') log(LogLevel.INFO, 'num vertices {}'.format(mesh.num_vertices())) log( LogLevel.INFO, 'Number of dofs: {}'.format( mesh.num_vertices() * (1 + parameters['general']['dim']))) # import pdb; pdb.set_trace() with open(os.path.join(outdir, 'parameters.yaml'), "w") as f: yaml.dump(parameters, f, default_flow_style=False) R = parameters['geometry']['R'] ell = parameters['material']['ell'] savelag = 1 # left = dolfin.CompiledSubDomain("near(x[0], -Lx/2.)", Lx=Lx) # right = dolfin.CompiledSubDomain("near(x[0], Lx/2.)", Lx=Lx) # left_bottom_pt = dolfin.CompiledSubDomain("near(x[0],-Lx/2.) && near(x[1],-Ly/2.)", Lx=Lx, Ly=Ly) mf = dolfin.MeshFunction("size_t", mesh, 1, 0) # right.mark(mf, 1) # left.mark(mf, 2) ds = dolfin.Measure("ds", subdomain_data=mf) dx = dolfin.Measure("dx", metadata=form_compiler_parameters, domain=mesh) # Function Spaces V_u = dolfin.VectorFunctionSpace(mesh, "CG", 1) V_alpha = dolfin.FunctionSpace(mesh, "CG", 1) u = dolfin.Function(V_u, name="Total displacement") u.rename('u', 'u') alpha = Function(V_alpha) alpha_old = dolfin.Function(alpha.function_space()) alpha.rename('alpha', 'alpha') dalpha = TrialFunction(V_alpha) alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) state = {'u': u, 'alpha': alpha} Z = dolfin.FunctionSpace( mesh, dolfin.MixedElement([u.ufl_element(), alpha.ufl_element()])) z = dolfin.Function(Z) v, beta = dolfin.split(z) # ut = dolfin.Expression("t", t=0.0, degree=0) # bcs_u = [dolfin.DirichletBC(V_u, dolfin.Constant((0,0)), left), # dolfin.DirichletBC(V_u, dolfin.Constant((0,0)), right), # dolfin.DirichletBC(V_u, (0, 0), left_bottom_pt, method="pointwise") # ] bcs_u = [dolfin.DirichletBC(V_u, dolfin.Constant((0., 0.)), 'on_boundary')] # bcs_u = [] # bcs_alpha_l = DirichletBC(V_alpha, Constant(0.0), left) # bcs_alpha_r = DirichletBC(V_alpha, Constant(0.0), right) # bcs_alpha =[bcs_alpha_l, bcs_alpha_r] # bcs_alpha = [DirichletBC(V_alpha, Constant(0.0), 'on_boundary')] bcs_alpha = [] # bcs_alpha = [DirichletBC(V_alpha, Constant(1.), boundary_meshfunction, 101)] bcs = {"damage": bcs_alpha, "elastic": bcs_u} ell = parameters['material']['ell'] # Problem definition # Problem definition k_res = parameters['material']['k_res'] a = (1 - alpha)**2. + k_res w_1 = parameters['material']['sigma_D0']**2 / parameters['material']['E'] w = w_1 * alpha eps = sym(grad(u)) eps0t = Expression([['t', 0.], [0., 't']], t=0., degree=0) X0 = parameters['geometry']['R'] lmbda0 = parameters['material']['E'] * parameters['material']['nu'] / ( 1. - parameters['material']['nu'])**2. mu0 = parameters['material']['E'] / 2. / (1.0 + parameters['material']['nu']) nu = parameters['material']['nu'] # Wt = a*parameters['material']['E']*nu/(2*(1-nu**2.)) * tr(eps-eps0t)**2. \ # + a*parameters['material']['E']*(inner(eps-eps0t, eps-eps0t)/(2.*(1+nu))) \ # + 1./2.*1./parameters['material']['ell_e']**2.*dot(u, u) # effective coeff of trace = lmbda mu / (lmbda + 2 mu) = nu/(1-nu) # Wt = a* lmbda0/(lmbda0+ 2.*mu0) * tr(eps-eps0t)**2. \ # + a*2.*mu0*(inner(eps-eps0t, eps-eps0t)) \ Wt = a*parameters['material']['E']*nu/((1+nu)*(1-2*nu)) * tr(eps-eps0t)**2. \ + a*parameters['material']['E']*(inner(eps-eps0t, eps-eps0t)/(2.*(1+nu))) \ + 1./2.*X0**2./parameters['material']['ell_e']**2.*dot(u, u) energy = Wt * dx + w_1 * (alpha + (parameters['material']['ell'] / X0**2.) * inner(grad(alpha), grad(alpha))) * dx file_out = dolfin.XDMFFile(os.path.join(outdir, "output.xdmf")) file_out.parameters["functions_share_mesh"] = True file_out.parameters["flush_output"] = True file_postproc = dolfin.XDMFFile(os.path.join(outdir, "postprocess.xdmf")) file_postproc.parameters["functions_share_mesh"] = True file_postproc.parameters["flush_output"] = True file_eig = dolfin.XDMFFile(os.path.join(outdir, "perturbations.xdmf")) file_eig.parameters["functions_share_mesh"] = True file_eig.parameters["flush_output"] = True file_bif = dolfin.XDMFFile(os.path.join(outdir, "bifurcation.xdmf")) file_bif.parameters["functions_share_mesh"] = True file_bif.parameters["flush_output"] = True file_bif_postproc = dolfin.XDMFFile( os.path.join(outdir, "bifurcation_postproc.xdmf")) file_bif_postproc.parameters["functions_share_mesh"] = True file_bif_postproc.parameters["flush_output"] = True solver = EquilibriumSolver(energy, state, bcs, parameters=parameters) stability = StabilitySolver(energy, state, bcs, parameters=parameters) # stability = StabilitySolver(energy, state, bcs, parameters = parameters['stability'], rayleigh= [rP, rN]) linesearch = LineSearch(energy, state) load_steps = np.linspace(parameters['loading']['load_min'], parameters['loading']['load_max'], parameters['loading']['n_steps']) time_data = [] time_data_pd = [] spacetime = [] lmbda_min_prev = 1e-6 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurc_i = 0 alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) bifurcation_loads = [] perturb = False _file = dolfin.XDMFFile(os.path.join(outdir, "test.xdmf")) log(LogLevel.INFO, '{}'.format(parameters)) log( LogLevel.INFO, 'ell/X0 = {}, ell/ell_e = {}, ell_e/X0 = {}'.format( parameters['material']['ell'] / X0, parameters['material']['ell'] / parameters['material']['ell_e'], parameters['material']['ell_e'] / parameters['geometry']['R'])) break_after_bifurcation = False file_debug = dolfin.XDMFFile('/Users/kumiori/debugalpha.xdmf') file_debug.parameters["functions_share_mesh"] = True file_debug.parameters["flush_output"] = True from matplotlib import cm for step, load in enumerate(load_steps): log(LogLevel.INFO, '==========================================================') log(LogLevel.INFO, '====================== STEPPING ==========================') log(LogLevel.INFO, 'INFO: Solving load t = {:.2f}'.format(load)) alpha_old.assign(alpha) eps0t.t = load (time_data_i, am_iter) = solver.solve(debugpath=outdir) # Second order stability conditions (stable, negev) = stability.solve(solver.damage.problem.lb) log(LogLevel.INFO, 'Current state is{}stable'.format(' ' if stable else ' un')) mineig = stability.mineig if hasattr(stability, 'mineig') else 0.0 log(LogLevel.INFO, 'INFO: lmbda min {}'.format(lmbda_min_prev)) log(LogLevel.INFO, 'INFO: mineig {}'.format(mineig)) Deltav = (mineig - lmbda_min_prev) if hasattr(stability, 'eigs') else 0 if (mineig + Deltav) * (lmbda_min_prev + dolfin.DOLFIN_EPS) < 0 and not bifurcated: bifurcated = True # save 3 bif modes log(LogLevel.INFO, 'INFO: About to bifurcate load {} step {}'.format(load, step)) bifurcation_loads.append(load) modes = np.where(stability.eigs < 0)[0] bifurc_i += 1 lmbda_min_prev = mineig if hasattr(stability, 'mineig') else 0. # we postpone the update after the stability check if stable: solver.update() log( LogLevel.INFO, ' Current state is{}stable'.format( ' ' if stable else ' un')) else: # Continuation # save_current_bifurcation = True # save_stability = stability iteration = 1 while stable == False: log(LogLevel.CRITICAL, 'Continuation iteration {}'.format(iteration)) # # linesearch cont_data_pre = compile_continuation_data(state, energy) perturbation_v = stability.perturbation_v perturbation_beta = stability.perturbation_beta perturbation_v = stability.perturbations_v[0] perturbation_beta = stability.perturbations_beta[0] log(LogLevel.INFO, ' Perturbations') # log(LogLevel.INFO, '{}'.format(stability. perturbations_beta)) pert = [(_v, _b) for _v, _b in zip( stability.perturbations_v, stability.perturbations_beta)] for n in range(len(pert)): linesearch.search( { 'u': u, 'alpha': alpha, 'alpha_old': alpha_old }, pert[n][0], pert[n][1]) if size == 1: fig = plt.figure( figsize=(4, 1.5), dpi=180, ) _nmodes = len(pert) for mode in range(_nmodes): plt.subplot(2, int(_nmodes / 2) + _nmodes % 2, mode + 1) ax = plt.gca() plt.axis('off') plot(stability.perturbations_beta[mode], vmin=-1., vmax=1.) # ax.set_title('mode: '.format(mode)) fig.savefig(os.path.join(outdir, "modes-{:.3f}.pdf".format(load)), bbox_inches="tight") plt.close() fig = plt.figure(figsize=((_nmodes + 1) * 3, 3), dpi=80, facecolor='w', edgecolor='k') fig.suptitle('Load {:3f}'.format(load), fontsize=16) plt.subplot(2, _nmodes + 1, 1) plt.title('$\\alpha$ (max = {:2.2f})'.format( max(alpha.vector()[:]))) plt.set_cmap('coolwarm') plt.axis('off') plot(alpha, vmin=0., vmax=1.) plt.set_cmap('hot') for i, mode in enumerate(pert): plt.subplot(2, _nmodes + 1, i + 2) plt.axis('off') plot(mode[1], cmap=cm.ocean, rowspan=2) h_opt, bounds, energy_perturbations = linesearch.search( { 'u': u, 'alpha': alpha, 'alpha_old': alpha_old }, mode[0], mode[1]) # import pdb; pdb.set_trace() # plt.title('mode {}\n$\\lambda_{{{}}}={:.1e},$\n$h_opt$={:.3f}'.format( # i, i, stability.eigs[i], h_opt)) # print('plot mode {}'.format(i)) # plt.tight_layout(h_pad=0.0, pad=1.5) # plt.savefig(os.path.join(outdir, "modes-{:3.4f}.png".format(load))) for i, mode in enumerate(pert): plt.subplot(2, _nmodes + 1, _nmodes + 2 + 1 + i) plt.axis('off') _pert_beta = mode[1] _pert_v = mode[0] h_opt, bounds, energy_perturbations = linesearch.search( { 'u': u, 'alpha': alpha, 'alpha_old': alpha_old }, mode[0], mode[1]) # bounds = mode['interval'] # import pdb; pdb.set_trace() if bounds[0] == bounds[1] == 0: plt.plot(bounds[0], 0) else: hs = np.linspace(bounds[0], bounds[1], 100) z = np.polyfit( np.linspace(bounds[0], bounds[1], len(energy_perturbations)), energy_perturbations, parameters['stability']['order']) p = np.poly1d(z) plt.plot(hs, p(hs), c='k') plt.plot(np.linspace(bounds[0], bounds[1], len(energy_perturbations)), energy_perturbations, marker='o', c='k') # plt.axvline(mode['hstar']) plt.axvline(0, lw=.5, c='k') # plt.title('{}'.format(i)) plt.tight_layout(h_pad=1.5, pad=1.5) # plt.legend() plt.savefig( os.path.join(outdir, "modes-{:3.4f}.pdf".format(load))) plt.close(fig) plt.clf() log(LogLevel.INFO, 'INFO: plotted modes') h_opt, (hmin, hmax), energy_perturbations = linesearch.search( { 'u': u, 'alpha': alpha, 'alpha_old': alpha_old }, perturbation_v, perturbation_beta) log( LogLevel.INFO, 'h_opt {}, (hmin, hmax) {}, energy_perturbations {}'. format(h_opt, (hmin, hmax), energy_perturbations)) # # stable = True if h_opt != 0: log(LogLevel.INFO, ' Bifurcating') save_current_bifurcation = True alpha_bif.assign(alpha) alpha_bif_old.assign(alpha_old) # # admissible uval = u.vector()[:] + h_opt * perturbation_v.vector()[:] aval = alpha.vector( )[:] + h_opt * perturbation_beta.vector()[:] u.vector()[:] = uval alpha.vector()[:] = aval u.vector().vec().ghostUpdate() alpha.vector().vec().ghostUpdate() file_debug.write_checkpoint(alpha, 'alpha_new', 0, append=True) alpha.rename('alpha_new', 'alpha_new') file_debug.write(alpha) __v = alpha - alpha_old _v = dolfin.project(__v, V_alpha) file_debug.write(_v) alpha.rename('alpha', 'alpha') plt.clf() plt.colorbar(dolfin.plot(__v, cmap=cm.binary)) plt.savefig( '/Users/kumiori/apert-aold-{}-new-{}.pdf'.format( step, iteration)) # import pdb; pdb.set_trace() (time_data_i, am_iter) = solver.solve(debugpath=outdir) file_debug.write_checkpoint(alpha, 'alpha_new_post', 0, append=True) alpha.rename('alpha_new_post', 'alpha_new_post') file_debug.write(alpha) alpha.rename('alpha', 'alpha') (stable, negev) = stability.solve(solver.damage.problem.lb) log( LogLevel.INFO, ' Continuation iteration {}, current state is{}stable' .format(iteration, ' ' if stable else ' un')) iteration += 1 cont_data_post = compile_continuation_data(state, energy) criterion = (cont_data_post['energy'] - cont_data_pre['energy'] ) / cont_data_pre['energy'] < parameters[ 'stability']['cont_rtol'] log(LogLevel.INFO, 'INFO: Continuation criterion {}'.format(criterion)) else: # warn log(LogLevel.WARNING, 'Found zero increment, we are stuck in the matrix') log(LogLevel.WARNING, 'Continuing load program') import pdb pdb.set_trace() break # solver.update() # if save_current_bifurcation: # import pdb; pdb.set_trace() # time_data_i['h_opt'] = h_opt # time_data_i['max_h'] = hmax # time_data_i['min_h'] = hmin # modes = np.where(save_stability.eigs < 0)[0] # leneigs = len(modes) # maxmodes = min(3, leneigs) # with file_bif as file: # for n in range(maxmodes): # mode = dolfin.project(save_stability.linsearch[n]['beta_n'], V_alpha) # modename = 'beta-%d'%n # mode.rename(modename, modename) # log(LogLevel.INFO, 'Saved mode {}'.format(modename)) # file.write(mode, step) # with file_bif_postproc as file: # # leneigs = len(modes) # # maxmodes = min(3, leneigs) # beta0v = dolfin.project(save_stability.perturbation_beta, V_alpha) # log(LogLevel.DEBUG, 'DEBUG: irrev {}'.format(alpha.vector()-alpha_old.vector())) # file.write_checkpoint(beta0v, 'beta0', 0, append = True) # file.write_checkpoint(alpha_bif_old, 'alpha-old', 0, append=True) # file.write_checkpoint(alpha_bif, 'alpha-bif', 0, append=True) # file.write_checkpoint(alpha, 'alpha', 0, append=True) # # np.save(os.path.join(outdir, 'energy_perturbations-{}'.format(step)), energy_perturbations, allow_pickle=True, fix_imports=True) # if size == 1: # dolfin.plot(perturbation_beta) # plt.savefig(os.path.join(outdir, "pert_beta.pdf")) # with file_eig as file: # _v = dolfin.project(dolfin.Constant(h_opt)*perturbation_v, V_u) # _beta = dolfin.project(dolfin.Constant(h_opt)*perturbation_beta, V_alpha) # _v.rename('perturbation displacement', 'perturbation displacement') # _beta.rename('perturbation damage', 'perturbation damage') # file.write(_v, load) # file.write(_beta, load) # break_after_bifurcation = True time_data_i["load"] = load time_data_i["alpha_max"] = max(alpha.vector()[:]) time_data_i["elastic_energy"] = dolfin.assemble(a * Wt * dx) time_data_i["dissipated_energy"] = dolfin.assemble( (w + w_1 * material_parameters['ell']**2. * inner(grad(alpha), grad(alpha))) * dx) time_data_i["stable"] = stability.stable time_data_i["# neg ev"] = stability.negev time_data_i["eigs"] = stability.eigs if hasattr(stability, 'eigs') else np.inf log( LogLevel.INFO, "Load/time step {:.4g}: converged in iterations: {:3d}, err_alpha={:.4e}" .format(time_data_i["load"], time_data_i["iterations"][0], time_data_i["alpha_error"][0])) time_data.append(time_data_i) time_data_pd = pd.DataFrame(time_data) # import pdb; pdb.set_trace() # plt.figure() # plt1 = time_data_pd.plot( # x=time_data_pd["load"], # y=time_data_pd["iterations"], # marker=".", # logy=True, # logx=False, # ) # plt.savefig(os.path.join(outdir, "plot_err.pdf")) with file_out as file: file.write(alpha, load) file.write(u, load) with file_postproc as file: file.write_checkpoint(alpha, "alpha-{}".format(step), step, append=True) file.write_checkpoint(u, "u-{}".format(step), step, append=True) log(LogLevel.INFO, 'INFO: written postprocessing step {}'.format(step)) if break_after_bifurcation: log(LogLevel.CRITICAL, ' Bifurcarted. Breaking here') break # step = it # for s in range(step): # log(LogLevel.INFO, 'INFO: reading step {}'.format(s)) # f.read_checkpoint(alpha, "alpha-{}".format(s)) # log(LogLevel.INFO, 'INFO: read step {}'.format(step)) # f.close() # import pdb; pdb.set_trace() # spacetime.append(get_trace(alpha)) time_data_pd.to_json(os.path.join(outdir, "time_data.json")) if size == 1: def format_space(x, pos, xresol=100): return '$%1.1f$' % ((-x + xresol / 2) / xresol) def format_time(t, pos, xresol=100): return '$%1.1f$' % ((t - parameters['loading']['load_min']) / parameters['loading']['n_steps'] * parameters['loading']['load_max']) from matplotlib.ticker import FuncFormatter, MaxNLocator # ax = plt.gca() # ax.yaxis.set_major_formatter(FuncFormatter(format_space)) # ax.xaxis.set_major_formatter(FuncFormatter(format_time)) plot(alpha) plt.savefig(os.path.join(outdir, 'alpha.pdf')) log(LogLevel.INFO, "Saved figure: {}".format(os.path.join(outdir, 'alpha.pdf'))) return time_data_pd, outdir
u = w.sub(0).collapse() p = w.sub(1).collapse() # We can calculate the :math:`L^2` norms of u and p as follows:: print("Norm of velocity coefficient vector: %.15g" % u.vector().norm()) print("Norm of pressure coefficient vector: %.15g" % p.vector().norm()) # Check pressure norm pnorm = p.vector().norm() assert np.isclose(pnorm, 4147.69457577) # Finally, we can save and plot the solutions:: # Save solution in XDMF format with XDMFFile(MPI.comm_world, "velocity.xdmf") as ufile_xdmf: ufile_xdmf.write(u) with XDMFFile(MPI.comm_world, "pressure.xdmf") as pfile_xdmf: pfile_xdmf.write(p) # Plot solution plt.figure() plot(u, title="velocity") # plt.figure() plot(p, title="pressure" + str(MPI.rank(mesh.mpi_comm()))) # Display plots plt.show()
def test_hessian(eps_in): mesh = UnitSquareMesh(10, 10) param = {'eps': eps_in} NN = NuclearNormSVD2D(mesh, param) NN2 = NuclearNormformula(mesh, param) direc12 = Function(NN.VV) m1h, m2h = Function(NN.V), Function(NN.V) H = [1e-4, 1e-5, 1e-6, 1e-7] mpicomm = mesh.mpi_comm() mpirank = MPI.rank(mpicomm) mpisize = MPI.size(mpicomm) if mpirank == 0: print '-------------------------------------' print 'Test Hessian. eps={}'.format(eps) print '-------------------------------------' M1 = [interpolate(Expression("x[0] + x[1]", degree=10), NN.V), interpolate(Expression("x[0] * x[1]", degree=10), NN.V), interpolate(Expression("x[0]*x[0] + x[1]", degree=10), NN.V), interpolate(Expression('log(10 - ' + \ '(pow(pow(x[0]-0.5,2)+pow(x[1]-0.5,2),0.5)<0.4) * (' + \ '4*(x[0]<=0.5) + 8*(x[0]>0.5) ))', degree=10), NN.V), interpolate(Expression('log(10 - ' + \ '(pow(pow(x[0]-0.5,2)+pow(x[1]-0.5,2),0.5)<0.4) * 8 )', degree=10), NN.V)] M2 = [interpolate(Expression("x[0] + x[1]", degree=10), NN.V), interpolate(Expression("1.0 + cos(x[0])", degree=10), NN.V), interpolate(Expression("x[1]*x[1] + x[0]", degree=10), NN.V), interpolate(Expression('log(10 - ' + \ '(pow(pow(x[0]-0.5,2)+pow(x[1]-0.5,2),0.5)<0.4) * (' + \ '8*(x[0]<=0.5) + 4*(x[0]>0.5) ))', degree=10), NN.V), interpolate(Expression('log(10 - ' + \ '(pow(pow(x[0]-0.5,2)+pow(x[1]-0.5,2),0.5)<0.4) * (' + \ '8*(x[0]<=0.5) + 4*(x[0]>0.5) ))', degree=10), NN.V)] tt = 1 for m1, m2 in zip(M1, M2): if mpirank == 0: print '\nTest {}'.format(tt) tt += 1 NN2.assemble_hessianab(m1, m2) for nn in range(5): if mpirank == 0: print '--direction {}'.format(nn) direc1 = interpolate(Expression('1 + sin(n*pi*x[0])*sin(n*pi*x[1])',\ n=nn, degree=10), NN.V) direc2 = interpolate(Expression('1 + cos(n*pi*x[0])*cos(n*pi*x[1])',\ n=nn, degree=10), NN.V) assign(direc12.sub(0), direc1) assign(direc12.sub(1), direc2) Hv = NN2.hessianab(direc1.vector(), direc2.vector()) HMv = (NN2.H + NN2.sMass) * direc12.vector() nHv = norm(Hv) nHMv = norm(HMv) ndiff = norm(Hv - HMv) / nHv if mpirank == 0: print '|Hv|={}, |HMV|={}, |diff|={:.2e}'.format( nHv, nHMv, ndiff) for hh in H: setfct(m1h, m1) m1h.vector().axpy(hh, direc1.vector()) setfct(m2h, m2) m2h.vector().axpy(hh, direc2.vector()) grad1 = NN.gradab(m1h, m2h) setfct(m1h, m1) m1h.vector().axpy(-hh, direc1.vector()) setfct(m2h, m2) m2h.vector().axpy(-hh, direc2.vector()) grad2 = NN.gradab(m1h, m2h) FD = (grad1 - grad2) / (2.0 * hh) nFD = norm(FD) if nHv > 1e-16: err = norm(FD - Hv) / nHv else: err = norm(FD - Hv) if mpirank == 0: print '\th={}, |FD|={}, err={:.2e}'.format(hh, nFD, err), if err < 1e-6: if mpirank == 0: print '\t =>> OK!' break else: if mpirank == 0: print ''
plt.ioff() import dolfin as dl from dolfin import MPI, mpi_comm_world dl.set_log_active(False) from fenicstools.objectivefunctional import ObjFctalElliptic from fenicstools.plotfenics import PlotFenics from fenicstools.prior import LaplacianPrior from fenicstools.regularization import TV, TVPD from fenicstools.observationoperator import ObsPointwise from fenicstools.optimsolver import checkgradfd_med, checkhessfd_med mpicomm = mpi_comm_world() mpirank = MPI.rank(mpicomm) mpisize = MPI.size(mpicomm) PLOT = False CHECK = True mesh = dl.UnitSquareMesh(150, 150) V = dl.FunctionSpace(mesh, 'Lagrange', 2) # space for state and adjoint variables Vm = dl.FunctionSpace(mesh, 'Lagrange', 1) # space for medium parameter Vme = dl.FunctionSpace(mesh, 'Lagrange', 1) # sp for target med param def u0_boundary(x, on_boundary): return on_boundary
solve, split, sym, parameters, FiniteElement, VectorElement, MixedElement, BoxMesh) import LAB from constants import mesh_width, mesh_height, nx, ny, nz parameters['form_compiler']['optimize'] = True parameters['form_compiler']['cpp_optimize'] = True parameters['form_compiler']['cpp_optimize_flags'] = '-O3 -march=native' parameters['form_compiler']['representation'] = 'quadrature' # To show parameter information; print(info(parameters, True)) set_log_level(ERROR) COMM = mpi_comm_world() RANK = MPI.rank(COMM) IS_MAIN_PROC = RANK == 0 rho_0 = 3300.0 rho_melt = 2900.0 darcy = 1e-13 # k over (mu*phi) in darcy alpha = 2.5e-5 g = 9.81 # not actually used.. (in cian's notes he is using the non dimensional # kappa in the equations, which here i have defined as 1 (as # kappa/kappa_0) so i think i can get away with this) kappa = 1.0E-6 b = 12.7 cc = math.log(128) # Ep = 0.014057
import dolfin as dl import numpy as np import sys from fenicstools.linalg.lumpedmatrixsolver import LumpedMatrixSolverS, LumpedMassMatrixPrime from fenicstools.miscfenics import setfct from dolfin import MPI, mpi_comm_world mycomm = mpi_comm_world() mpisize = MPI.size(mycomm) mpirank = MPI.rank(mycomm) #@profile def run(): mesh = dl.UnitSquareMesh(50, 50) Vr = dl.FunctionSpace(mesh, 'Lagrange', 1) Vphi = dl.FunctionSpace(mesh, 'Lagrange', 2) Vphidofmap = Vphi.dofmap().dofs() test, trial = dl.TestFunction(Vphi), dl.TrialFunction(Vphi) u, v = dl.Function(Vphi), dl.Function(Vphi) rho = dl.Function(Vr) Mweak = dl.inner(rho * test, trial) * dl.dx Mprime = LumpedMassMatrixPrime(Vr, Vphi, None) h = 1e-5 fact = [1.0, -1.0] RHO = \ [dl.interpolate(dl.Expression('2.0 + sin(n*pi*x[0])*sin(n*pi*x[1])', n=1.0, degree=10), Vr), \ dl.interpolate(dl.Expression('2.0 + sin(n*pi*x[0])*sin(n*pi*x[1])', n=8.0, degree=10), Vr), \
def newtonsolver(F, J_nonlinear, A_pre, A, b, bcs, lmbda, recompute, recompute_tstep, compiler_parameters, dvp_, up_sol, dvp_res, rtol, atol, max_it, counter, verbose, restart_folder, **namespace): """ Solve the non-linear system of equations with Newton scheme. The standard is to compute the Jacobian every time step, however this is computationally costly. We have therefore added two parameters for re-computing only every 'recompute' iteration, or for every 'recompute_tstep' time step. Setting 'recompute' to != 1 is faster, but can impact the convergence rate. Altering 'recompute_tstep' is considered an advanced option, and should be used with care. """ # Initial values iter = 0 residual = 10**8 rel_res = 10**8 # Capture if residual increases from last iteration last_rel_res = residual last_residual = rel_res while rel_res > rtol and residual > atol and iter < max_it: # Check if recompute Jacobian from 'recompute_tstep' (time step) recompute_for_timestep = iter == 0 and (counter % recompute_tstep == 0) # Check if recompute Jacobian from 'recompute' (iteration) recompute_frequency = iter > 0 and iter % recompute == 0 # Recompute Jacobian due to increased residual recompute_residual = iter > 0 and (last_rel_res < rel_res or last_residual < residual) if recompute_for_timestep or recompute_frequency or recompute_residual or restart_folder is not None: if MPI.rank(MPI.comm_world) == 0 and verbose: print("Compute Jacobian matrix") A = assemble(J_nonlinear, tensor=A, form_compiler_parameters=compiler_parameters, keep_diagonal=True) A.axpy(1.0, A_pre, True) A.ident_zeros() [bc.apply(A) for bc in bcs] up_sol.set_operator(A) # Compute right hand side b = assemble(-F, tensor=b) # Apply boundary conditions and solve [bc.apply(b, dvp_["n"].vector()) for bc in bcs] up_sol.solve(dvp_res.vector(), b) dvp_["n"].vector().axpy(lmbda, dvp_res.vector()) [bc.apply(dvp_["n"].vector()) for bc in bcs] # Reset residuals last_residual = residual last_rel_res = rel_res # Check residual residual = b.norm('l2') rel_res = norm(dvp_res, 'l2') if rel_res > 1E20 or residual > 1E20: raise RuntimeError( "Error: The simulation has diverged during the Newton solve.") if MPI.rank(MPI.comm_world) == 0 and verbose: print( "Newton iteration %d: r (atol) = %.3e (tol = %.3e), r (rel) = %.3e (tol = %.3e) " % (iter, residual, atol, rel_res, rtol)) iter += 1 return dict(up_sol=up_sol, A=A)
def test_mesh_construction_pygmsh(): import pygmsh if MPI.rank(MPI.comm_world) == 0: geom = pygmsh.opencascade.Geometry() geom.add_ball([0.0, 0.0, 0.0], 1.0, char_length=0.2) points, cells, _, _, _ = pygmsh.generate_mesh(geom) else: points = numpy.zeros([0, 3]) cells = { "tetra": numpy.zeros([0, 4], dtype=numpy.int64), "triangle": numpy.zeros([0, 3], dtype=numpy.int64), "line": numpy.zeros([0, 2], dtype=numpy.int64) } mesh = dolfin.cpp.mesh.Mesh(MPI.comm_world, dolfin.cpp.mesh.CellType.Type.tetrahedron, points, cells['tetra'], [], cpp.mesh.GhostMode.none) assert mesh.degree() == 1 assert mesh.geometry.dim == 3 assert mesh.topology.dim == 3 mesh = dolfin.cpp.mesh.Mesh(MPI.comm_world, dolfin.cpp.mesh.CellType.Type.triangle, points, cells['triangle'], [], cpp.mesh.GhostMode.none) assert mesh.degree() == 1 assert mesh.geometry.dim == 3 assert mesh.topology.dim == 2 mesh = dolfin.cpp.mesh.Mesh(MPI.comm_world, dolfin.cpp.mesh.CellType.Type.interval, points, cells['line'], [], cpp.mesh.GhostMode.none) assert mesh.degree() == 1 assert mesh.geometry.dim == 3 assert mesh.topology.dim == 1 if MPI.rank(MPI.comm_world) == 0: print("Generate mesh") geom = pygmsh.opencascade.Geometry() geom.add_ball([0.0, 0.0, 0.0], 1.0, char_length=0.2) points, cells, _, _, _ = pygmsh.generate_mesh( geom, extra_gmsh_arguments=['-order', '2']) print("End Generate mesh", cells.keys()) else: points = numpy.zeros([0, 3]) cells = { "tetra10": numpy.zeros([0, 10], dtype=numpy.int64), "triangle6": numpy.zeros([0, 6], dtype=numpy.int64), "line3": numpy.zeros([0, 3], dtype=numpy.int64) } mesh = dolfin.cpp.mesh.Mesh(MPI.comm_world, dolfin.cpp.mesh.CellType.Type.tetrahedron, points, cells['tetra10'], [], cpp.mesh.GhostMode.none) assert mesh.degree() == 2 assert mesh.geometry.dim == 3 assert mesh.topology.dim == 3 mesh = dolfin.cpp.mesh.Mesh(MPI.comm_world, dolfin.cpp.mesh.CellType.Type.triangle, points, cells['triangle6'], [], cpp.mesh.GhostMode.none) assert mesh.degree() == 2 assert mesh.geometry.dim == 3 assert mesh.topology.dim == 2
experiment = sys.argv[1] print("record: True/False") record = True#input() # Optimization options for the form compiler parameters["krylov_solver"]["maximum_iterations"] = 300 parameters["krylov_solver"]["relative_tolerance"] = 1.0e-10 parameters["krylov_solver"]["absolute_tolerance"] = 1.0e-10 # ================= MPI PARAMETERS ================= # # MPI Parameters comm = MPI.comm_world rank = MPI.rank(comm) # Set log level for parallel set_log_level(LogLevel.ERROR) if rank == 0: set_log_level(LogLevel.PROGRESS) # ================= GEOMETRY PARAMETERS ================= # rd = 0.4 # disk radius xc = 0.0 # x-coordinate of the center of the disk yc = -5.0 # y-coordinate of the center of the disk Lpml = 1.0 # width of the PML layer Lx = 10.0 # width of the interior domain Ly = 10.0 # heigth of the interior domain
""" Winter simulation on a trough bed where conductivity remains constant but sliding decreases. Bump height 5cm. """ from dolfin import * from dolfin import MPI, mpi_comm_world from sheet_model import * from constants import * from scale_functions import * # Process number MPI_rank = MPI.rank(mpi_comm_world()) # Scale functions for determining winter sliding speed input_file = '../inputs_sheet/steady/ref_trough_steady_5cm.hdf5' scale_functions = ScaleFunctions(input_file, 1.1e-2, 1.1e-2, u_b_max=100.0) prm = NonlinearVariationalSolver.default_parameters() prm['newton_solver']['relaxation_parameter'] = 1.0 prm['newton_solver']['relative_tolerance'] = 1e-7 prm['newton_solver']['absolute_tolerance'] = 1e-7 prm['newton_solver']['error_on_nonconvergence'] = False prm['newton_solver']['maximum_iterations'] = 30 model_inputs = {} pcs['k'] = 1.1e-2 pcs['h_r'] = 0.05 pcs['l_r'] = 1.0 model_inputs['input_file'] = input_file model_inputs['out_dir'] = 'out_trough_sliding_only_hr_5cm/'
def create_mesh(self, parameters): from dolfin import Point, XDMFFile import hashlib d = { 'rad': parameters['geometry']['rad'], 'rad2': parameters['geometry']['rad2'], 'meshsize': parameters['geometry']['meshsize'] } fname = 'circle' meshfile = "meshes/%s-%s.xml" % (fname, self.signature) if os.path.isfile(meshfile): # already existing mesh print("Meshfile %s exists" % meshfile) else: # mesh_template = open('scripts/sandwich_pert.template.geo' ) print("Create meshfile, meshsize {}".format( parameters['geometry']['meshsize'])) nel = int(parameters['geometry']['rad'] / parameters['geometry']['meshsize']) # geom = mshr.Circle(Point(0., 0.), parameters['geometry']['rad']) # mesh = mshr.generate_mesh(geom, nel) mesh_template = open('scripts/coin.geo') src = Template(mesh_template.read()) geofile = src.substitute(d) if MPI.rank(MPI.comm_world) == 0: with open("scripts/coin-%s" % self.signature + ".geo", 'w') as f: f.write(geofile) # cmd = 'gmsh scripts/coin-{}.geo -2 -o meshes/coin-{}.msh'.format(self.signature, self.signature) # print(check_output([cmd], shell=True)) # run in shell mode in case you are not run in terminal # cmd = 'dolfin-convert -i gmsh meshes/coin-{}.msh meshes/coin-{}.xml'.format(self.signature, self.signature) # Popen([cmd], stdout=PIPE, shell=True).communicate() # mesh_xdmf = XDMFFile("meshes/%s-%s.xdmf"%(fname, self.signature)) # mesh_xdmf.write(mesh) form_compiler_parameters = { "representation": "uflacs", "quadrature_degree": 2, "optimize": True, "cpp_optimize": True, } # import pdb; pdb.set_trace() mesh = Mesh("meshes/coin.xml") self.domains = MeshFunction('size_t', mesh, 'meshes/coin_physical_region.xml') # dx = dx(subdomain_data=domains) # plt.figure() # plot(self.domains) # visuals.setspines0() # plt.savefig(os.path.join(self.outdir,'domains-{}.pdf' # .format(hashlib.md5(str(d).encode('utf-8')).hexdigest()))) self.ds = Measure("exterior_facet", domain=mesh) self.dS = Measure("interior_facet", domain=mesh) self.dx = Measure("dx", metadata=form_compiler_parameters, subdomain_data=self.domains) return mesh