Beispiel #1
0
def run_inv(config_file):
    """Run the inversion part of the simulation"""
    # Read run config file
    params = ConfigParser(config_file)

    inout.setup_logging(params)
    inout.log_preamble("inverse", params)

    # Load the static model data (geometry, smb, etc)
    input_data = inout.InputData(params)

    # Get the model mesh
    mesh = fice_mesh.get_mesh(params)
    mdl = model.model(mesh, input_data, params)

    # pts_lengthscale = params.obs.pts_len

    mdl.gen_alpha()

    # Add random noise to Beta field iff we're inverting for it
    mdl.bglen_from_data()
    mdl.init_beta(mdl.bglen_to_beta(mdl.bglen), pert=False)

    # Next line will output the initial guess for alpha fed into the inversion
    # File(os.path.join(outdir,'alpha_initguess.pvd')) << mdl.alpha

    #####################
    # Run the Inversion #
    #####################

    slvr = solver.ssa_solver(mdl)
    slvr.inversion()

    ##############################################
    #  Write out variables in outdir and         #
    #  diagnostics folder                        #
    #############################################

    phase_name = params.inversion.phase_name
    phase_suffix = params.inversion.phase_suffix
    outdir = Path(params.io.output_dir) / phase_name / phase_suffix
    diag_dir = Path(params.io.diagnostics_dir)

    # Required for next phase (HDF5):

    invout_file = params.io.inversion_file

    phase_suffix = params.inversion.phase_suffix
    if len(phase_suffix) > 0:
        invout_file = params.io.run_name + phase_suffix + '_invout.h5'

    invout = HDF5File(mesh.mpi_comm(), str(outdir / invout_file), 'w')

    invout.parameters.add("gamma_alpha", slvr.gamma_alpha)
    invout.parameters.add("delta_alpha", slvr.delta_alpha)
    invout.parameters.add("gamma_beta", slvr.gamma_beta)
    invout.parameters.add("delta_beta", slvr.delta_beta)
    invout.parameters.add("delta_beta_gnd", slvr.delta_beta_gnd)
    invout.parameters.add("timestamp", str(datetime.datetime.now()))

    invout.write(mdl.alpha, 'alpha')
    invout.write(mdl.beta, 'beta')

    # For visualisation (XML & VTK):
    if params.io.write_diagnostics:

        inout.write_variable(slvr.U,
                             params,
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)
        inout.write_variable(mdl.beta,
                             params,
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)

        mdl.beta_bgd.rename("beta_bgd", "")
        inout.write_variable(mdl.beta_bgd,
                             params,
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)

        inout.write_variable(mdl.bed,
                             params,
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)
        H = project(mdl.H, mdl.M)
        H.rename("thick", "")
        inout.write_variable(H,
                             params,
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)

        fl_ex = project(slvr.float_conditional(H), mdl.M)
        inout.write_variable(fl_ex,
                             params,
                             name='float',
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)

        inout.write_variable(mdl.mask_vel_M,
                             params,
                             name="mask_vel",
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)

        inout.write_variable(mdl.u_obs_Q,
                             params,
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)
        inout.write_variable(mdl.v_obs_Q,
                             params,
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)
        inout.write_variable(mdl.u_std_Q,
                             params,
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)
        inout.write_variable(mdl.v_std_Q,
                             params,
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)

        U_obs = project((mdl.v_obs_Q**2 + mdl.u_obs_Q**2)**(1.0 / 2.0), mdl.M)
        U_obs.rename("uv_obs", "")
        inout.write_variable(U_obs,
                             params,
                             name="uv_obs",
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)

        inout.write_variable(mdl.alpha,
                             params,
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)

        Bglen = project(slvr.beta_to_bglen(slvr.beta), mdl.M)
        Bglen.rename("Bglen", "")
        inout.write_variable(Bglen,
                             params,
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)
        inout.write_variable(slvr.bmelt,
                             params,
                             name="bmelt",
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)
        inout.write_variable(slvr.smb,
                             params,
                             name="smb",
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)
        inout.write_variable(mdl.surf,
                             params,
                             name="surf",
                             outdir=diag_dir,
                             phase_name=phase_name,
                             phase_suffix=phase_suffix)

    return mdl
Beispiel #2
0
def run_forward(config_file):

    # Read run config file
    params = ConfigParser(config_file)
    log = inout.setup_logging(params)
    inout.log_preamble("forward", params)

    outdir = params.io.output_dir
    diag_dir = params.io.diagnostics_dir
    phase_name = params.time.phase_name

    # Load the static model data (geometry, smb, etc)
    input_data = inout.InputData(params)

    # Get model mesh
    mesh = fice_mesh.get_mesh(params)

    # Define the model
    mdl = model.model(mesh, input_data, params)

    mdl.alpha_from_inversion()
    mdl.beta_from_inversion()

    # Solve
    slvr = solver.ssa_solver(mdl, mixed_space=params.inversion.dual)
    slvr.save_ts_zero()

    cntrl = slvr.get_control()

    qoi_func = slvr.get_qoi_func()

    # TODO here - cntrl now returns a list - so compute_gradient returns a list of tuples

    # Run the forward model
    Q = slvr.timestep(adjoint_flag=1, qoi_func=qoi_func)
    # Run the adjoint model, computing gradient of Qoi w.r.t cntrl
    dQ_ts = compute_gradient(Q, cntrl)  # Isaac 27

    # Output model variables in ParaView+Fenics friendly format
    # Output QOI & DQOI (needed for next steps)
    inout.write_qval(slvr.Qval_ts, params)
    inout.write_dqval(dQ_ts, [var.name() for var in cntrl], params)

    # Output final velocity, surface & thickness (visualisation)
    inout.write_variable(slvr.U,
                         params,
                         name="U_fwd",
                         outdir=diag_dir,
                         phase_name=phase_name,
                         phase_suffix=params.time.phase_suffix)
    inout.write_variable(mdl.surf,
                         params,
                         name="surf_fwd",
                         outdir=diag_dir,
                         phase_name=phase_name,
                         phase_suffix=params.time.phase_suffix)

    H = project(mdl.H, mdl.Q)
    inout.write_variable(H,
                         params,
                         name="H_fwd",
                         outdir=diag_dir,
                         phase_name=phase_name,
                         phase_suffix=params.time.phase_suffix)
    return mdl
def main(dd, infile, outfile, noise_sdev, L, seed=0, ls=None):
    """
    Take velocity data from run_momsolve.py and add gaussian noise. This is used
    for synthetic cases (ismipc/ice_stream) where there is no real velocity
    observations.

    dd - (string/path) directory where input is found & where output is written
    infile - (string/path) input file name (.h5)
    outfile - (string/path) output file name (.h5)
    noise_sdev - (float) standard deviation of added noise
    L - (float) Length of domain
    seed - (int) Random seed
    ls - (float [optional]) Spacing between points in a new grid

    Expects an HDF5 file (containing both mesh & velocity function) as input.
    In the case of a periodic boundary condition with NxN elements, this
    produces NxN velocity observations (NOT N+1 x N+1) because otherwise
    boundary nodes would be doubly constrained.

    If 'ls' is not provided, data will remain on the input grid.
    """

    assert Path(infile).suffix == ".h5"
    assert Path(outfile).suffix == ".h5"
    assert noise_sdev > 0.0

    infile = HDF5File(MPI.comm_world, str(Path(dd) / infile), 'r')

    # Get mesh from file
    mesh = Mesh()
    infile.read(mesh, 'mesh', False)
    periodic_bc = bool(infile.attributes('mesh')['periodic'])

    if periodic_bc:
        assert L > 0.0
        V = VectorFunctionSpace(mesh,
                                'Lagrange',
                                1,
                                dim=2,
                                constrained_domain=model.PeriodicBoundary(L))

    else:
        V = VectorFunctionSpace(mesh, 'Lagrange', 1, dim=2)

    # Read the velocity
    U = Function(V)
    infile.read(U, 'U')
    infile.close()

    if ls is not None:

        # Get the mesh coordinates (only to set bounds)
        mc = mesh.coordinates()
        xmin = mc[:, 0].min()
        xmax = mc[:, 0].max()

        ymin = mc[:, 1].min()
        ymax = mc[:, 1].max()

        # Generate ls-spaced points
        xc = np.arange(xmin + ls / 2.0, xmax, ls)
        yc = np.arange(ymin + ls / 2.0, ymax, ls)

        # Pretty hacky - turn these into a rectangular mesh
        # because it makes periodic interpolation easier
        pts_mesh = RectangleMesh(Point(xc[0], yc[0]), Point(xc[-1], yc[-1]),
                                 len(xc) - 1,
                                 len(yc) - 1)
        pts_space = VectorFunctionSpace(pts_mesh, 'Lagrange', degree=1, dim=2)

        U_pts = project(U, pts_space)

    else:
        U_pts = U

    # How many points?
    ndofs = int(U_pts.vector()[:].shape[0] / 2)

    # Generate the random noise
    np.random.seed(seed)
    u_noise = np.random.normal(scale=noise_sdev, size=ndofs)
    v_noise = np.random.normal(scale=noise_sdev, size=ndofs)

    # Grab the two components of the velocity vector, and add noise
    U_vec = U_pts.vector()[:]
    U_vec[0::2] += u_noise
    U_vec[1::2] += v_noise

    u_array = U_vec[0::2]
    v_array = U_vec[1::2]

    # [::2] because tabulate_dof_coordinates produces two copies
    # (because 2 dofs per node...)
    x, y = np.hsplit(U_pts.function_space().tabulate_dof_coordinates()[::2], 2)

    # Produce output as raw points & vel
    output = h5py.File(Path(dd) / outfile, 'w')

    output.create_dataset("x", x.shape, dtype=x.dtype, data=x)

    output.create_dataset("y", x.shape, dtype=x.dtype, data=y)

    output.create_dataset("u_obs", x.shape, dtype=np.float64, data=u_array)

    output.create_dataset("v_obs", x.shape, dtype=np.float64, data=v_array)

    noise_arr = np.zeros_like(x)
    noise_arr[:] = noise_sdev

    output.create_dataset("u_std", x.shape, dtype=np.float64, data=noise_arr)

    output.create_dataset("v_std", x.shape, dtype=np.float64, data=noise_arr)

    mask_arr = np.ones_like(x)

    output.create_dataset("mask_vel", x.shape, dtype=np.float64, data=mask_arr)
Beispiel #4
0
    Qp = fice_mesh.get_periodic_space(params, mesh, dim=1)
    V = fice_mesh.get_periodic_space(params, mesh, dim=2)

U_file = str(next(results_dir.glob("*U.xml")))
alpha_file = str(next(results_dir.glob("*alpha.xml")))
uv_obs_file = str(next(results_dir.glob("*uv_obs.xml")))
alpha_sigma_file = str(next(results_dir.glob("*alpha_sigma.xml")))

U = Function(V, U_file)
alpha = Function(Qp, alpha_file)
uv_obs = Function(M, uv_obs_file)
alpha_sigma = Function(Qp, alpha_sigma_file)
# B2 = Function(M, os.path.join(dd,'B2.xml'))

u, v = U.split()
uv = project(sqrt(u * u + v * v), Q)
uv_diff = project(uv_obs - uv, Q)
B2 = project(alpha * alpha, M)

x = mesh.coordinates()[:, 0]
y = mesh.coordinates()[:, 1]
t = mesh.cells()

fig = plt.figure(figsize=(10, 5))

ax = fig.add_subplot(231)
ax.set_aspect('equal')
v = B2.compute_vertex_values(mesh)
minv = np.min(v)
maxv = np.max(v)
levels = np.linspace(minv, maxv, numlev)
def main(config_file):

    print(
        "===WARNING=== - this code has not been fully adapted to new config format"
    )
    print("Consult TODOs in run_balancemeltrates.py")

    init_yr = 5  #TODO - where in the config?

    #Read run config file
    params = ConfigParser(config_file)

    log = inout.setup_logging(params)
    inout.log_preamble("balance meltrates", params)

    dd = params.io.input_dir
    outdir = params.io.output_dir
    run_length = params.time.run_length
    n_steps = params.time.total_steps

    assert init_yr < run_length

    # #Load Data
    # param = pickle.load( open( os.path.join(dd,'param.p'), "rb" ) )

    # param['outdir'] = outdir
    # param['sliding_law'] = sl
    # param['picard_params'] = {"nonlinear_solver":"newton",
    #             "newton_solver":{"linear_solver":"umfpack",
    #             "maximum_iterations":25,
    #             "absolute_tolerance":1.0e-3,
    #             "relative_tolerance":5.0e-2,
    #             "convergence_criterion":"incremental",
    #             "error_on_nonconvergence":False,
    #             "lu_solver":{"same_nonzero_pattern":False, "symmetric":False, "reuse_factorization":False}}}

    #Load Data
    mesh = Mesh(os.path.join(outdir, 'mesh.xml'))

    M = FunctionSpace(mesh, 'DG', 0)
    #TODO - what's the logic here?:
    Q = FunctionSpace(
        mesh, 'Lagrange',
        1)  # if os.path.isfile(os.path.join(dd,'param.p')) else M

    mask = Function(M, os.path.join(outdir, 'mask.xml'))

    if os.path.isfile(os.path.join(outdir, 'data_mesh.xml')):
        data_mesh = Mesh(os.path.join(outdir, 'data_mesh.xml'))
        Mdata = FunctionSpace(data_mesh, 'DG', 0)
        data_mask = Function(Mdata, os.path.join(outdir, 'data_mask.xml'))
    else:
        data_mesh = mesh
        data_mask = mask

    if not params.mesh.periodic_bc:
        Qp = Q
        V = VectorFunctionSpace(mesh, 'Lagrange', 1, dim=2)
    else:
        Qp = fice_mesh.get_periodic_space(params, mesh, dim=1)
        V = fice_mesh.get_periodic_space(params, mesh, dim=2)

    #Load fields
    U = Function(V, os.path.join(outdir, 'U.xml'))

    alpha = Function(Qp, os.path.join(outdir, 'alpha.xml'))
    beta = Function(Qp, os.path.join(outdir, 'beta.xml'))
    bed = Function(Q, os.path.join(outdir, 'bed.xml'))

    smb = Function(M, os.path.join(outdir, 'smb.xml'))
    thick = Function(M, os.path.join(outdir, 'thick.xml'))
    mask_vel = Function(M, os.path.join(outdir, 'mask_vel.xml'))
    u_obs = Function(M, os.path.join(outdir, 'u_obs.xml'))
    v_obs = Function(M, os.path.join(outdir, 'v_obs.xml'))
    u_std = Function(M, os.path.join(outdir, 'u_std.xml'))
    v_std = Function(M, os.path.join(outdir, 'v_std.xml'))
    uv_obs = Function(M, os.path.join(outdir, 'uv_obs.xml'))

    mdl = model.model(mesh, data_mask, params,
                      init_fields=False)  # TODO initialization
    mdl.init_bed(bed)
    mdl.init_thick(thick)
    mdl.gen_surf()
    mdl.init_mask(mask)
    mdl.init_vel_obs(u_obs, v_obs, mask_vel, u_std, v_std)
    mdl.init_lat_dirichletbc()
    mdl.init_bmelt(Constant(0.0))
    mdl.init_alpha(alpha)
    mdl.init_beta(beta, False)
    mdl.init_smb(smb)
    mdl.label_domain()

    #Solve
    slvr = solver.ssa_solver(mdl)
    slvr.save_ts_zero()
    slvr.timestep(save=1, adjoint_flag=0)

    #Balance melt rates

    #Load time series of ice thicknesses
    hdf = HDF5File(slvr.mesh.mpi_comm(), os.path.join(outdir, 'H_ts.h5'), "r")
    attr = hdf.attributes("H")
    nsteps = attr['count']

    #model time step
    dt = params.time.dt

    #Model iterations to difference between
    iter_s = np.ceil(init_yr / dt)  #Iteration closest to 5yr
    iter_f = nsteps - 1  #Final iteration
    dT = dt * (iter_f - iter_s)  #Time diff in years between iterations

    #Read iteration data
    HS = Function(slvr.M)
    HF = Function(slvr.M)
    hdf.read(HS, "H/vector_{0}".format(int(iter_s)))
    hdf.read(HF, "H/vector_{0}".format(int(iter_f)))

    #Mask out grounded region
    rhow = params.constants.rhow
    rhoi = params.constants.rhoi
    H_s = -rhow / rhoi * bed
    fl_ex = conditional(slvr.H_init <= H_s, Constant(1.0), Constant(0.0))

    #Calculate bmelt
    bmelt = project(ufl.Max(fl_ex * (HF - HS) / dT, Constant(0.0)), slvr.M)

    #Output model variables in ParaView+Fenics friendly format
    with open(os.path.join(outdir, 'bmeltrate_param.p'), "wb") as bmeltfile:
        pickle.dump(mdl.param, bmeltfile)

    # File(os.path.join(outdir,'mesh.xml')) << mdl.mesh

    vtkfile = File(os.path.join(outdir, 'bmelt.pvd'))
    xmlfile = File(os.path.join(outdir, 'bmelt.xml'))
    vtkfile << bmelt
    xmlfile << bmelt

    return mdl