Example #1
0
    def set(self, m3d):

        ny = self.ny
        y0 = self.y0
        tracer = self.tracer
        input = self.input

        text = ""
        if input is not None:
            file = util.get_hdf5_file(m3d, self, input)
            text = text + "set from input file:\n  {}\n".format(file.filename)
        else:
            values = [t[1] for t in tracer]
            text = text + "set from init values:\n"
            text = text + "  {:10} {}\n".format("name", "value")

        for i in range(ny):
            # Name, Value, Unit, Description
            name = str(tracer[i][0])
            value = float(tracer[i][1])
            if input is not None:
                util.set_vector_from_hdf5_file(m3d, y0[i], file, name)
            else:
                y0[i].set(value)
                text = text + "  {:10.10} {:<16e}\n".format(name, value)

        text = text.rstrip()
        util.debug(m3d, self, text, level=1)
Example #2
0
    def __init__(self, m3d):

        # get 'grid_mask' variable from file
        filepath = util.get_key(m3d, self, m3d.config, "Grid", str)
        gridfile = util.get_hdf5_file(m3d, self, filepath)
        grid = util.get_key(m3d, self, gridfile, "grid_mask",
                            Dataset)  #gridfile["grid_mask"]

        # masks
        self.mask3d = mask3d = (grid[...] != grid.fillvalue)
        self.mask2d = mask2d = mask3d[0, ...]

        # not needed any more
        gridfile.close()

        # vector and profiles
        self.nv = nv = mask3d.sum()  # vector length
        self.np = mask2d.sum()  # profile count
        self.npi = mask3d.sum(axis=0)[mask2d]  # each profile length

        # index permutation from nc/3d to tmm/1d
        nc3d = mask3d[...].astype(">i4")
        (nz, ny, nx) = nc3d.shape
        nc3d[mask3d] = range(nv)
        nc3d[mask3d] = nc3d[mask3d] + 1
        nc1d = nc3d.reshape(nz, ny * nx).T.flat
        self.nc2tmm = nc1d[nc1d != 0] - 1

        # debug
        util.debug(m3d, self, self, level=1)
Example #3
0
    def __init__(self, m3d):

        self.config = config = m3d.config.get("BGC")
        if config is None:
            self.use_bgc = False
        else:
            self.use_bgc = True
            self.name = util.get_key(m3d, self, config, "Name", str)

            # load bgc module
            # must be placed in metos3d/bgc/<<name>>/<<sources>>
            # must be compiled with: f2py -c <<sources>> -m <<name>>
            # call to bgc routine must apply to:
            # fortran: metos3dbgc(ny, nx, nu, nb, nd, dt, q, t, y, u, b, d)
            # python: metos3dbgc(dt,q,t,y,u,b,d,[ny,nx,nu,nb,nd])
            # module name: exchange '-' to '_'
            modname = self.name.replace("-", "_")
            self.mod = importlib.import_module("bgc." + self.name + "." +
                                               modname)

            self.init_parameter(m3d)
            self.init_boundary_data(m3d)
            self.init_domain_data(m3d)

        # debug
        util.debug(m3d, self, self, level=1)
Example #4
0
    def solve(self, m3d):
        util.debug(m3d, self, "Solve ...", level=1)

        tracer = m3d.tracer
        time = m3d.time

        ny = tracer.ny
        y0 = tracer.y0

        nl = self.nl
        yl = self.yl

        i = 0
        #        print("rank: {}, i: {}, y[i]: {}, y0[i]: {}".format(m3d.rank, i, yl[i], y0[i]))
        util.copy_vector_list(y0, yl)
        #        print("rank: {}, i: {}, y[i]: {}, y0[i]: {}".format(m3d.rank, i, yl[i], y0[i]))
        #        for i in range(ny):
        #            print("rank: {}, i: {}, y[i]: {}, y0[i]: {}".format(m3d.rank, i, yl[i], y0[i]))
        ##            yl[i] = y0[i]
        #            y0[i].copy(yl[i])
        ##            yl[i].copy(y0[i])
        #            print("rank: {}, i: {}, y[i]: {}, y0[i]: {}".format(m3d.rank, i, yl[i], y0[i]))
        #        import sys
        #        sys.exit(1)

        for i in range(nl):
            util.debug(m3d, self, "{}".format(i), level=1)
            time.step(m3d, yl)
Example #5
0
    def __init__(self, m3d):

        comm = m3d.comm
        grid = m3d.grid

        # store own copy of comm for __str__
        self.comm = m3d.comm

        self.size = size = comm.size
        self.rank = rank = comm.rank

        # vector length, profile count, profile depths
        nv = grid.nv
        np = grid.np
        npi = grid.npi

        # profiles to processes
        starts = npi.cumsum() - npi
        weights = starts + 0.5 * npi
        ranks = numpy.floor((weights / nv) * size)

        # profiles per process
        punique, pindex, pcount = numpy.unique(ranks,
                                               return_index=True,
                                               return_counts=True)
        pprev = pcount.cumsum() - pcount

        # vector shares
        vcount = numpy.array(
            [npi[i:i + c].sum() for i, c in zip(pindex, pcount)])
        vprev = vcount.cumsum() - vcount

        # my rank
        self.nploc = pcount[rank]
        self.npprev = pprev[rank]
        self.nvloc = vcount[rank]
        self.nvprev = vprev[rank]

        # index pointers for bgc
        #        numpy.append(0, numpy.cumsum(nnzrow)).astype("i4")
        self.npiloc = npi[self.npprev:self.npprev + self.nploc]
        self.indptr = numpy.append(0, numpy.cumsum(npi))
        self.indptrloc = numpy.append(0, numpy.cumsum(self.npiloc))
        #        self.np_indptr = numpy.append(0, numpy.cumsum(npi[self.npprev:self.npprev+self.nploc]))
        #        self.

        # compute max diff to optimal
        self.opt = opt = float(nv) / size
        self.maxdiff = maxdiff = numpy.amax(
            numpy.abs(numpy.array(vcount) - opt))

        # debug
        util.debug(m3d, self, self, level=1)
Example #6
0
    def set(self, m3d):

        text = ""
        if self.use_boundary:
            nb = self.nb
            nbi = self.nbi
            b = self.b
            boundary = self.boundary
            path = self.boundary_path
            text = text + "boundary:\n"
            text = text + "  {:10.10} {}\n".format("name", "file")
            for i in range(nb):
                # Name, Count, Description, Unit, File
                varname = boundary[i][0]
                filename = boundary[i][4]
                file = util.get_hdf5_file(m3d, self, path + filename)
                text = text + "  {:10.10} {}\n".format(varname,
                                                       path + filename)
                for j in range(nbi[i]):
                    pass
                    util.set_vector_from_hdf5_file(m3d,
                                                   b[i][j],
                                                   file,
                                                   varname,
                                                   index=j)

        if self.use_domain:
            nd = self.nd
            ndi = self.ndi
            d = self.d
            domain = self.domain
            path = self.domain_path
            text = text + "domain:\n"
            text = text + "  {:10.10} {}\n".format("name", "file")
            for i in range(nd):
                # Name, Count, Description, Unit, File
                varname = domain[i][0]
                filename = domain[i][4]
                file = util.get_hdf5_file(m3d, self, path + filename)
                text = text + "  {:10.10} {}\n".format(varname,
                                                       path + filename)
                for j in range(ndi[i]):
                    util.set_vector_from_hdf5_file(m3d,
                                                   d[i][j],
                                                   file,
                                                   varname,
                                                   index=j)

        text = text.rstrip()
        util.debug(m3d, self, text, level=1)
Example #7
0
    def __init__(self, m3d):

        self.config = config = m3d.config.get("TMM")
        if config is None:
            self.use_tmm = False
        else:
            self.use_tmm = True

            self.path = util.get_key(m3d, self, config, "Path", str)
            self.init_explicit(m3d)
            self.init_implicit(m3d)

        # debug
        util.debug(m3d, self, self, level=1)
Example #8
0
    def __init__(self, m3d):

        config = util.get_key(m3d, self, m3d.config, "Solver", dict)

        self.type = util.get_key(m3d, self, config, "Type", str)
        self.nl = util.get_key(m3d, self, config, "Count", int)
        self.mon = util.get_key(m3d, self, config, "Monitor", bool)

        self.yl = []
        for y in m3d.tracer.y0:
            self.yl.append(y.duplicate())

        # debug
        util.debug(m3d, self, self, level=1)
Example #9
0
    def __init__(self, m3d):

        config = util.get_key(m3d, self, m3d.config, "Time", dict)

        self.t0 = util.get_key(m3d, self, config, "Start", float)
        self.nt = util.get_key(m3d, self, config, "Count", int)
        self.dt = util.get_key(m3d, self, config, "Step", float)

        tracer = m3d.tracer
        ny = tracer.ny
        y0 = tracer.y0

        bgc = m3d.bgc
        b = bgc.b
        nb = bgc.nb
        nbi = bgc.nbi
        bj = []
        for bi in b:
            bj.append(bi[0].duplicate())
        self.bj = bj

        d = bgc.d
        nd = bgc.nd
        ndi = bgc.ndi
        dj = []
        for di in d:
            dj.append(di[0].duplicate())
        self.dj = dj

        yj = []
        yexpj = []
        qj = []
        for yi in y0:
            yj.append(yi.duplicate())
            yexpj.append(yi.duplicate())
            qi = yi.duplicate()
            qi.zeroEntries()
            qi.assemble()
            qj.append(qi)
        self.yj = yj
        self.yexpj = yexpj
        self.qj = qj

        # debug
        util.debug(m3d, self, self, level=1)
Example #10
0
    def __init__(self, m3d):

        config = util.get_key(m3d, self, m3d.config, "Tracer", dict)
        self.tracer = tracer = util.get_key(m3d, self, config,
                                            "Name, Value, Unit, Description",
                                            list)
        self.output = config.get("Output")
        self.input = config.get("Input")

        # global and local vector length
        nv = m3d.grid.nv
        nvloc = m3d.load.nvloc

        self.ny = ny = len(tracer)
        self.y0 = util.create_petsc_vectors(ny, (nvloc, nv))

        # debug
        util.debug(m3d, self, self, level=1)
Example #11
0
    def run(self):
        """
            runs a simulation,
            loop over model years, spin up
            perform time steps,
            interpolate, boundary and domain data, matrices,
            evaluate bgc model,
            apply transport,
            
            u = [u1, ..., um]
            bj = [[]]
            dj = [[]]
            yj = [yj1, ..., yjny]
            qj = [qj1, ..., qjny]
            Aimpj = diag([Aimpj, ..., Aimpj])
            Aexpj = diag([Aexpj, ..., Aexpj])
            
            yjp1 = Aimpj * (Aexpj * yj + qj(dt, tj, yj, u, bj, dj))
            
            yjp1 = [yjp11, ..., yjp1ny]
            
        """
        util.debug(self, self, "--- set " + 100 * "-", level=1)
        self.tracer.set(self)
        self.bgc.set(self)
        self.tmm.set(self)

        util.debug(self, self, "--- solve " + 100 * "-", level=1)
        self.solver.solve(self)

        util.debug(self, self, "--- save " + 100 * "-", level=1)
        self.tracer.save(self)
Example #12
0
    def __init__(self, argv):
        """
            check computation model ...
            print version,
            print number of processes,
            attributes ...
            creates instances ...
            initialize metos3d context,

            Parameters:
                argv:   list with command arguments, file path of yaml conf file

        """

        # version and runtime context
        self.version = version = VERSION
        self.comm = comm = PETSc.COMM_WORLD
        self.size = size = comm.size
        self.rank = rank = comm.rank

        # config
        self.config = util.get_config_from_yaml_file(self, argv)

        # debug level
        self.debug = util.get_key(self, self, self.config, "Debug", int)
        util.debug(self, self, "--- init " + 100 * "-", level=1)
        util.debug(self, self, self, level=1)

        # init
        self.grid = Grid(self)
        self.load = Load(self)
        self.tracer = Tracer(self)
        self.bgc = BGC(self)
        self.tmm = TMM(self)
        self.time = Time(self)
        self.solver = Solver(self)
Example #13
0
    def step(self, m3d, yl):
        util.debug(m3d, self, "time step ...", level=1)

        tracer = m3d.tracer
        ny = tracer.ny
        y0 = tracer.y0

        bgc = m3d.bgc
        u = bgc.u

        tmm = m3d.tmm

        t0 = self.t0
        dt = self.dt
        nt = self.nt
        yj = self.yj
        qj = self.qj
        yexpj = self.yexpj
        bj = self.bj
        dj = self.dj

        if m3d.tmm.use_tmm:
            if m3d.tmm.use_explicit:
                self.Aexpj = m3d.tmm.Aexp[0].duplicate()
            if m3d.tmm.use_implicit:
                self.Aimpj = m3d.tmm.Aimp[0].duplicate()

        Aexpj = self.Aexpj
        Aimpj = self.Aimpj

        for i in range(ny):
            yj[i] = yl[i]

        tstart = time.time()
        for j in range(nt):
            tstartdelta = time.time()
            tj = t0 + j * dt

            if bgc.use_bgc:
                #                util.debug(m3d, self, "use_bgc", level=1)

                if bgc.use_boundary:
                    util.debug(m3d, self, "use_boundary", level=1)
                    b = bgc.b
                    nb = bgc.nb
                    nbi = bgc.nbi
                    # interpolate
                    for ib in range(nb):
                        alpha, ialpha, beta, ibeta = util.interpolate(
                            nbi[ib], tj)
                        #                        bj[ib] = alpha * b[ib][ialpha] + beta * b[ib][ibeta]
                        bj[ib] = b[ib][ialpha]  # VecCopy
                        bj[ib] = alpha * bj[ib]  # VecScale
                        bj[ib] = bj[ib] + beta * b[ib][ibeta]  # VecAXPY

                if bgc.use_domain:
                    util.debug(m3d, self, "use_domain", level=1)
                    d = bgc.d
                    nd = bgc.nd
                    ndi = bgc.ndi
                    # interpolate
                    for id in range(nd):
                        alpha, ialpha, beta, ibeta = util.interpolate(
                            ndi[id], tj)
                        #                        dj[id] = alpha * d[id][ialpha] + beta * d[id][ibeta]
                        dj[id] = d[id][ialpha]  # VecCopy
                        dj[id] = alpha * dj[id]  # VecScale
                        dj[id] = dj[id] + beta * d[id][ibeta]  # VecAXPY

#                qj[0].view()
                m3d.bgc.q(m3d, dt, qj, tj, yj, u, bj, dj)
#                yj[0].view()
#                qj[0].view()

#                import sys

#                print(dt)
#                print(qj)
#                print(yj)
#                qj[0].view()
#                print(qj[0][:])
#                print(qj[1][:])
#                print(yj[0][:])
#                print(yj[1][:])
#                print(u)
#                print(bj)
#                print(dj)
#                sys.stdout.flush()

#                sys.exit(1)

# if bgc.use_bgc:   qj is set to sms
# else:             qj stays zero

            if tmm.use_tmm:
                #                util.debug(m3d, self, "use_tmm", level=1)

                if tmm.use_explicit:
                    #                    util.debug(m3d, self, "use_explicit", level=1)
                    nexp = tmm.nexp
                    Aexp = tmm.Aexp
                    # interpolate
                    alpha, ialpha, beta, ibeta = util.interpolate(nexp, tj)
                    #                    print((alpha, ialpha, beta, ibeta))
                    #                    Aexpj = alpha * Aexp[ialpha] + beta * Aexp[ibeta]
                    Aexpj = Aexp[ialpha]  # MatCopy
                    Aexpj = alpha * Aexpj  # MatScale
                    Aexpj = Aexpj + beta * Aexp[ibeta]  # MatAXPY

                    #                    Aexp[ialpha].view()
                    #                    print(Aexpj.assembled)

                    # apply explicit
                    #                    m3d.tmm.apply(m3d, Aexpj, yj)
                    for i in range(ny):
                        #                        Aexpj.multAdd(yj[i], qj[i], yexpj[i])
                        yexpj[i] = Aexpj * yj[i] + qj[i]

#                    yexpj[0].view()
#                    print(yj[0][:10])
#                    print(qj[0][:10])
#                    print(yexpj[0][:10])
#                    print((Aexp[0]*yj[0])[:10])

#            else:
#                # we need to copy at least one time
#                yexpj = yj

#                #add bgc
#                if bgc.use_bgc:
#                    util.debug(m3d, self, "use_bgc", level=1)
#                    for i in range(ny):
#                        yexpj[i] = yexpj[i] + qj[i]
##                    yexpj = yexpj + qj

                if tmm.use_implicit:
                    #                    util.debug(m3d, self, "use_implicit", level=1)
                    nimp = tmm.nimp
                    Aimp = tmm.Aimp
                    # interpolate
                    alpha, ialpha, beta, ibeta = util.interpolate(nimp, tj)
                    #                    Aimpj = alpha * Aimp[ialpha] + beta * Aimp[ibeta]
                    Aimpj = Aimp[ialpha]  # MatCopy
                    Aimpj = alpha * Aimpj  # MatScale
                    Aimpj = Aimpj + beta * Aimp[ibeta]  # MatAXPY

                    # apply implicit
                    #                    m3d.tmm.apply(m3d, Aimpj, yj)
                    #                    yj = Aimpj*yexpj
                    for i in range(ny):
                        yj[i] = Aimpj * yexpj[i]

#                    yj[0].view()

            tenddelta = time.time()
            util.debug(m3d,
                       self,
                       "j: {:05d}, tj: {:f}, delta: {:.3f}, s: {:.3f}".format(
                           j, tj, tenddelta - tstartdelta, tenddelta - tstart),
                       level=1)
Example #14
0
    def set(self, m3d):

        if not self.use_tmm:
            util.debug(m3d, self, "none", level=1)
            return
        else:
            nv = m3d.grid.nv
            nvloc = m3d.load.nvloc

            # explicit
            self.nexp = 0
            self.Aexp = []
            if self.use_explicit:
                util.debug(m3d, self, "explicit ...", level=1)

                # Name, Count, File
                self.nexp = nexp = self.explicit[1]
                filepath = self.path + self.explicit[2]

                # we assume petsc mat aij format in a hdf5 file
                f = util.get_hdf5_file(m3d, self, filepath)
                nrow = f["nrow"].size
                ncol = f["ncol"].size
                nnz = f["nnz"].size
                nnzrow = f["nnzrow"]
                nnzrow_max = numpy.max(nnzrow)

                # however, we use index pointers for the petsc call
                indptr = numpy.append(0, numpy.cumsum(nnzrow)).astype("i4")
                colidx = f["colidx"]
                if not nv == nrow == ncol:
                    util.error(
                        m3d,
                        "Dimensions of explicit matrix: {} do not match vector length: {}"
                        .format((nrow, ncol), nv))
                    sys.exit(1)

                for i in range(nexp):
                    aij = f["aij"][i, ...]
                    A = PETSc.Mat()
                    A.create()
                    A.setType("aij")  # PETSc.Mat.Type.AIJ,
                    A.setSizes(((nvloc, nv), (nvloc, nv)))
                    A.setUp()

                    start, end = A.owner_range
                    A.setPreallocationNNZ((nnzrow_max, nnzrow_max))
                    A.setValuesCSR(indptr[start:end + 1] - indptr[start],
                                   colidx[indptr[start]:indptr[end]],
                                   aij[indptr[start]:indptr[end]])
                    A.assemble()

                    self.Aexp.append(A)

            # implcit
            self.nimp = 0
            self.Aimp = []
            if self.use_implicit:
                util.debug(m3d, self, "implicit ...", level=1)

                self.nimp = nimp = self.implicit[1]
                filepath = self.path + self.implicit[2]

                # we assume petsc mat aij format in a hdf5 file
                f = util.get_hdf5_file(m3d, self, filepath)
                nrow = f["nrow"].size
                ncol = f["ncol"].size
                nnz = f["nnz"].size
                nnzrow = f["nnzrow"]
                nnzrow_max = numpy.max(nnzrow)

                # however, we use index pointers for the petsc call
                indptr = numpy.append(0, numpy.cumsum(nnzrow)).astype("i4")
                colidx = f["colidx"]
                if not nv == nrow == ncol:
                    util.error(
                        m3d,
                        "Dimensions of implicit matrix: {} do not match vector length: {}"
                        .format((nrow, ncol), nv))
                    sys.exit(1)

                for i in range(nimp):
                    aij = f["aij"][i, ...]
                    A = PETSc.Mat()
                    A.create()
                    A.setType("aij")  # PETSc.Mat.Type.AIJ,
                    A.setSizes(((nvloc, nv), (nvloc, nv)))
                    A.setUp()

                    start, end = A.owner_range
                    A.setPreallocationNNZ((nnzrow_max, nnzrow_max))
                    A.setValuesCSR(indptr[start:end + 1] - indptr[start],
                                   colidx[indptr[start]:indptr[end]],
                                   aij[indptr[start]:indptr[end]])
                    A.assemble()

                    self.Aimp.append(A)
Example #15
0
 def save(self, m3d):
     util.debug(m3d, self, "Tracer: save {}".format(""), level=1)