Exemplo n.º 1
0
 def scatter_1D(self, positions, values, field, location, add_info):
     if self.root == True:
         positions, pos_ind = self.mesh.sortPositionsByMeshes(positions,
                                                              return_ind=[],
                                                              surface=True)
         values = [values[i] for i in pos_ind]
         add_info = [add_info[i] for i in pos_ind]
         location = self.mesh.sortIndexByMeshes(location, shift=False)
     pos = positions.pop(0)
     val = values.pop(0)
     info = add_info.pop(0)
     loc = location.pop(0)
     for child in self.children:
         loc_i = copy.copy(location[0])
         child.scatter_1D(positions, values, field, location, add_info)
         array_1D = location_indexes_inv(loc_i, store=False)
         nonzero = numpy.flatnonzero(field[array_1D])
         array_1D = array_1D[nonzero]
         pos = numpy.append(pos,
                            child.mesh.getPosition(
                                child.mesh.location_sat[nonzero]),
                            axis=0)
         val = numpy.append(val, field[array_1D])
         info = numpy.append(info, child.mesh.direction_sat[nonzero])
     if len(self.children) > 0:
         field[location_indexes_inv(loc, store=False)] *= 0
     self.scatter_1D_aux(pos, val, field, loc, info)
Exemplo n.º 2
0
    def scatter_1D_aux(self,
                       positions,
                       values,
                       field,
                       general_location,
                       add_info,
                       prec=10**(-c.INDEX_PREC)):
        #Creating 1-1 connection between local satellite nodes and general nodes
        dic = {
            loc_i: gen_i
            for loc_i, gen_i in zip(self.mesh.location_sat, general_location)
        }
        #Getting mesh coordinates
        mc = self.mesh.getIndex(positions)
        index = mc.astype(int)
        array = self.mesh.indexToArray(index)

        #Calcualting array indexes with respect to the whole domain
        array_gen = [dic[i] for i in array]
        #Getting the correct indexes for the field
        array_1D = location_indexes_inv(array_gen, store=False)
        horizontal = numpy.equal(add_info % 2, 0)
        vertical = numpy.logical_not(horizontal)
        dindex = numpy.where(horizontal, mc[:, 0] - index[:, 0],
                             mc[:, 1] - index[:, 1])

        filter_1D = dindex > prec

        #Adapting horizontal and vertical such that n_index works for inner boundaries as well as outer boundaries
        #mask = numpy.ones_like(add_info, dtype = numpy.bool_)
        #for boundary in self.mesh.boundaries:
        #    if boundary.type == Inner_2D_Rectangular.type:
        #        mask[numpy.flatnonzero(numpy.isin(array, boundary.location))] = False
        #horizontal = numpy.logical_or(horizontal, mask)
        #vertical = numpy.logical_and(vertical, numpy.logical_not(mask))
        #n_index = numpy.where(horizontal, array_1D+1, array_1D+2)
        #n_index = numpy.where(numpy.logical_and(vertical, array_1D == 0), n_index-2+self.mesh.nxsat, n_index)
        #n_index = numpy.where(numpy.logical_and(vertical, array_1D == len(self.mesh.location_sat)-1-self.mesh.nxsat), n_index-2+self.mesh.nxsat, n_index)

        # Finding the other node involved
        temp_location_indexes_inv = {
            locations: indexes[0]
            for indexes, locations in numpy.ndenumerate(self.mesh.location_sat)
        }
        loc_ind = numpy.asarray(
            [temp_location_indexes_inv.get(ind_i) for ind_i in array],
            dtype=numpy.uint16)
        n_index = [
            self.mesh.adjacent_sat[loc_ind[i]][add_info[i]]
            for i in range(len(array_1D))
        ]
        n_index = location_indexes_inv(
            [dic[self.mesh.location_sat[ind]] for ind in n_index], store=False)

        #scatter process
        numpy.add.at(field, array_1D, (1 - dindex) * values)
        numpy.add.at(field, n_index[filter_1D],
                     dindex[filter_1D] * values[filter_1D])
Exemplo n.º 3
0
    def scatter_1D(self,
                   positions,
                   values,
                   field,
                   location,
                   add_info,
                   prec=10**(-c.INDEX_PREC)):
        #Getting mesh coordinates
        mc = self.mesh.getIndex(positions)

        index = mc.astype(int)
        array = self.mesh.indexToArray(index)
        array_1D = location_indexes_inv(array, store=False)
        horizontal = numpy.equal(add_info % 2, 0)
        vertical = numpy.logical_not(horizontal)
        dindex = numpy.where(horizontal, mc[:, 0] - index[:, 0],
                             mc[:, 1] - index[:, 1])
        #n_index = numpy.where(horizontal, array_1D+1, array_1D+2)
        #n_index = numpy.where(numpy.logical_and(vertical, array_1D == 0), n_index-2+self.mesh.nxsat, n_index)
        #n_index = numpy.where(numpy.logical_and(vertical, array_1D == len(location)-1-self.mesh.nxsat), n_index-2+self.mesh.nxsat, n_index)
        n_index = numpy.asarray([
            self.mesh.adjacent_sat[array_1D[i]][add_info[i]]
            for i in range(len(array_1D))
        ],
                                dtype=numpy.uint16)

        filter_i = dindex > prec

        values = values * numpy.ones_like(
            (dindex)) if type(values) != numpy.ndarray else values
        numpy.add.at(field, array_1D, (1 - dindex) * values)
        numpy.add.at(field, n_index[filter_i],
                     dindex[filter_i] * values[filter_i])
Exemplo n.º 4
0
    def createDistributionAtBorder(self,
                                   location,
                                   part_solver,
                                   species,
                                   delta_n,
                                   prec=1e-5):
        add_rand = numpy.random.rand(len(location))
        #This needs to be generalized later
        #NOTE: Modified(2021/02/14) with no backward compatibility
        local_loc = location_indexes_inv(location, store=False)
        mpf_new = delta_n * self.areas[local_loc]

        #Treating borders
        mpf_new /= numpy.where(
            numpy.max(part_solver.pic.mesh.volumes) /
            part_solver.pic.mesh.volumes[location] > 3, 2, 1)

        #Computing number of particles created
        mpf_new = mpf_new / species.spwt + species.mesh_values.residuals[
            location] + add_rand
        mp_new = mpf_new.astype(int)
        species.mesh_values.residuals[location] = mpf_new - mp_new

        #Assigning positions
        pos_1 = numpy.repeat(part_solver.pic.mesh.getPosition(location),
                             mp_new,
                             axis=0)
        random = numpy.random.rand(numpy.shape(pos_1)[0])
        random += numpy.where(random == 0, 1e-3, 0)
        hit_1 = numpy.repeat(self.directions[local_loc], mp_new)
        ind_b = numpy.flatnonzero(hit_1 == 0)
        ind_l = numpy.flatnonzero(hit_1 == 3)
        ind_r = numpy.flatnonzero(hit_1 == 1)
        ind_t = numpy.flatnonzero(hit_1 == 2)

        #Bottom
        shifts = numpy.where(
            numpy.abs(pos_1[ind_b, 0] - self.xmin) < prec,
            random[ind_b] * part_solver.pic.mesh.dx / 2,
            (random[ind_b] - 0.5) * part_solver.pic.mesh.dx)
        shifts -= numpy.where(
            numpy.abs(pos_1[ind_b, 1] - self.xmax) < prec,
            random[ind_b] * part_solver.pic.mesh.dx / 2, 0)
        pos_1[ind_b, 0] += shifts
        #Left
        shifts = numpy.where(
            numpy.abs(pos_1[ind_l, 1] - self.ymin) < prec,
            random[ind_l] * part_solver.pic.mesh.dy / 2,
            (random[ind_l] - 0.5) * part_solver.pic.mesh.dy)
        shifts -= numpy.where(
            numpy.abs(pos_1[ind_l, 1] - self.ymax) < prec,
            random[ind_l] * part_solver.pic.mesh.dy / 2, 0)
        pos_1[ind_l, 1] += shifts
        #Right
        shifts = numpy.where(
            numpy.abs(pos_1[ind_r, 1] - self.ymin) < prec,
            random[ind_r] * part_solver.pic.mesh.dy / 2,
            (random[ind_r] - 0.5) * part_solver.pic.mesh.dy)
        shifts -= numpy.where(
            numpy.abs(pos_1[ind_r, 1] - self.ymax) < prec,
            random[ind_r] * part_solver.pic.mesh.dy / 2, 0)
        pos_1[ind_r, 1] += shifts
        #Top
        shifts = numpy.where(
            numpy.abs(pos_1[ind_t, 0] - self.xmin) < prec,
            random[ind_t] * part_solver.pic.mesh.dx / 2,
            (random[ind_t] - 0.5) * part_solver.pic.mesh.dx)
        shifts -= numpy.where(
            numpy.abs(pos_1[ind_t, 1] - self.xmax) < prec,
            random[ind_t] * part_solver.pic.mesh.dx / 2, 0)
        pos_1[ind_t, 0] += shifts

        repeats = numpy.ones(numpy.shape(hit_1)[0], dtype=numpy.uint8)
        return (numpy.append(pos_1, hit_1[:, None], axis=1), ), repeats
Exemplo n.º 5
0
    def createDistributionAtBorder(self,
                                   location,
                                   part_solver,
                                   species,
                                   delta_n,
                                   prec=1e-5):
        add_rand = numpy.random.rand(len(location))
        #NOTE: this should be generalized
        if self.material != 'space':
            local_loc = location_indexes_inv(location, store=False)
        else:
            c = 0
            local_loc = []
            for index, loc in numpy.ndenumerate(self.location):
                if loc == location[c]:
                    local_loc.append(index[0])
                    c += 1
            local_loc = numpy.asarray(local_loc, dtype='uint32')
        mpf_new = delta_n * self.areas[local_loc]
        mpf_new = mpf_new / species.spwt + species.mesh_values.residuals[
            location] + add_rand
        mp_new = mpf_new.astype(int)
        species.mesh_values.residuals[location] = mpf_new - mp_new

        #Assigning positions
        pos_1 = numpy.repeat(part_solver.pic.mesh.getPosition(location),
                             mp_new,
                             axis=0)
        random = numpy.random.rand(numpy.shape(pos_1)[0])
        #Bottom
        if self.directions[local_loc[0]] == 0:
            shifts = numpy.where(
                numpy.abs(pos_1[:, 0] - self.xmin) < prec,
                random * part_solver.pic.mesh.dx / 2,
                (random - 0.5) * part_solver.pic.mesh.dx)
            shifts -= numpy.where(
                numpy.abs(pos_1[:, 0] - self.xmax) < prec,
                random * part_solver.pic.mesh.dx / 2, 0)
            pos_1[:, 0] += shifts
            hit_1 = numpy.zeros_like(pos_1[:, 1], dtype=numpy.uint8)[:, None]
        #Left
        elif self.directions[local_loc[0]] == 3:
            shifts = numpy.where(
                numpy.abs(pos_1[:, 1] - self.ymin) < prec,
                random * part_solver.pic.mesh.dy / 2,
                (random - 0.5) * part_solver.pic.mesh.dy)
            shifts -= numpy.where(
                numpy.abs(pos_1[:, 1] - self.ymax) < prec,
                random * part_solver.pic.mesh.dy / 2, 0)
            pos_1[:, 1] += shifts
            hit_1 = 3 * numpy.ones_like(pos_1[:, 1], dtype=numpy.uint8)[:,
                                                                        None]
        #Right
        elif self.directions[local_loc[0]] == 1:
            shifts = numpy.where(
                numpy.abs(pos_1[:, 1] - self.ymin) < prec,
                random * part_solver.pic.mesh.dy / 2,
                (random - 0.5) * part_solver.pic.mesh.dy)
            shifts -= numpy.where(
                numpy.abs(pos_1[:, 1] - self.ymax) < prec,
                random * part_solver.pic.mesh.dy / 2, 0)
            pos_1[:, 1] += shifts
            hit_1 = numpy.ones_like(pos_1[:, 1], dtype=numpy.uint8)[:, None]
        #Top
        else:
            shifts = numpy.where(
                numpy.abs(pos_1[:, 0] - self.xmin) < prec,
                random * part_solver.pic.mesh.dx / 2,
                (random - 0.5) * part_solver.pic.mesh.dx)
            shifts -= numpy.where(
                numpy.abs(pos_1[:, 0] - self.xmax) < prec,
                random * part_solver.pic.mesh.dx / 2, 0)
            pos_1[:, 0] += shifts
            hit_1 = 2 * numpy.ones_like(pos_1[:, 1], dtype=numpy.uint8)[:,
                                                                        None]

        repeats = numpy.ones(numpy.shape(hit_1)[0], dtype=numpy.uint8)
        return (numpy.append(pos_1, hit_1, axis=1), ), repeats
Exemplo n.º 6
0
    def createDistributionAtBorder(self,
                                   location,
                                   part_solver,
                                   species,
                                   delta_n,
                                   prec=1e-5):
        #This needs to be generalized later
        #NOTE: Modified(2021/02/14) with no backward compatibility
        local_loc = location_indexes_inv(location, store=False)
        mpf_new = delta_n * self.areas[local_loc]

        #Treating borders
        y = (numpy.arange(part_solver.pic.mesh.nPoints) // part_solver.pic.
             mesh.nx) * part_solver.pic.mesh.dy + part_solver.pic.mesh.ymin
        if part_solver.pic.mesh.ymin == 0.0:
            y[:part_solver.pic.mesh.nx] = part_solver.pic.mesh.dy / 8
        dv = 2 * numpy.pi * y * part_solver.pic.mesh.dy * part_solver.pic.mesh.dx
        mpf_new /= numpy.where(
            numpy.abs(dv[location] / part_solver.pic.mesh.volumes[location] -
                      2) > 1e-3, 2, 1)

        #Computing number of particles created
        add_rand = numpy.random.rand(len(location))
        mpf_new = mpf_new / species.spwt + species.mesh_values.residuals[
            location] + add_rand
        mp_new = mpf_new.astype(int)
        species.mesh_values.residuals[location] = mpf_new - mp_new

        #Assigning positions
        pos = part_solver.pic.mesh.getPosition(location)
        pos_1 = numpy.repeat(pos, mp_new, axis=0)
        hit_1 = self.directions[local_loc]
        ind_b = hit_1 == 0
        ind_l = hit_1 == 3
        ind_r = hit_1 == 1
        ind_t = hit_1 == 2

        #Bottom
        random = numpy.random.rand(numpy.sum(mp_new[ind_b]))
        random += numpy.where(random == 0, 1e-3, 0)
        ind = numpy.repeat(ind_b, mp_new)
        shifts = numpy.where(
            numpy.abs(pos_1[ind, 0] - self.xmin) < prec,
            random * part_solver.pic.mesh.dx / 2,
            (random - 0.5) * part_solver.pic.mesh.dx)
        shifts -= numpy.where(
            numpy.abs(pos_1[ind, 0] - self.xmax) < prec,
            random * part_solver.pic.mesh.dx / 2, 0)
        pos_1[ind, 0] += shifts
        #Left
        rmin = numpy.where(pos[ind_l, 1] == self.ymin, pos[ind_l, 1],
                           pos[ind_l, 1] - part_solver.pic.mesh.dy / 2)
        rmax = numpy.where(pos[ind_l, 1] == self.ymax, pos[ind_l, 1],
                           pos[ind_l, 1] + part_solver.pic.mesh.dy / 2)
        pos_1[numpy.repeat(ind_l, mp_new),
              1] = cmt.randomYPositions_2D_cm(mp_new[ind_l], rmin, rmax)
        #Right
        rmin = numpy.where(pos[ind_r, 1] == self.ymin, pos[ind_r, 1],
                           pos[ind_r, 1] - part_solver.pic.mesh.dy / 2)
        rmax = numpy.where(pos[ind_r, 1] == self.ymax, pos[ind_r, 1],
                           pos[ind_r, 1] + part_solver.pic.mesh.dy / 2)
        pos_1[numpy.repeat(ind_r, mp_new),
              1] = cmt.randomYPositions_2D_cm(mp_new[ind_r], rmin, rmax)
        #Top
        random = numpy.random.rand(numpy.sum(mp_new[ind_t]))
        random += numpy.where(random == 0, 1e-3, 0)
        ind = numpy.repeat(ind_t, mp_new)
        shifts = numpy.where(
            numpy.abs(pos_1[ind, 0] - self.xmin) < prec,
            random * part_solver.pic.mesh.dx / 2,
            (random - 0.5) * part_solver.pic.mesh.dx)
        shifts -= numpy.where(
            numpy.abs(pos_1[ind, 0] - self.xmax) < prec,
            random * part_solver.pic.mesh.dx / 2, 0)
        pos_1[ind, 0] += shifts

        hit_1 = numpy.repeat(hit_1, mp_new)
        repeats = numpy.ones(numpy.shape(hit_1)[0], dtype=numpy.uint8)
        return (numpy.append(pos_1, hit_1[:, None], axis=1), ), repeats
Exemplo n.º 7
0
    def createDistributionAtBorder(self,
                                   location,
                                   part_solver,
                                   species,
                                   delta_n,
                                   prec=1e-5):
        add_rand = numpy.random.rand(len(location))
        local_loc = location_indexes_inv(location, store=False)
        mpf_new = delta_n * part_solver.pic.mesh.area_sat[local_loc]
        mpf_new = mpf_new / species.spwt + species.mesh_values.residuals[
            location] + add_rand
        mp_new = mpf_new.astype(int)
        species.mesh_values.residuals[location] = mpf_new - mp_new

        #Assigning positions
        pos_1 = numpy.repeat(part_solver.pic.mesh.getPosition(location),
                             mp_new,
                             axis=0)
        random = numpy.random.rand(numpy.shape(pos_1)[0])
        #Bottom
        if self.directions[local_loc[0]] == 0:
            shifts = numpy.where(
                numpy.abs(pos_1[:, 0] - self.xmin) < prec,
                random * part_solver.pic.mesh.dx / 2,
                (random - 0.5) * part_solver.pic.mesh.dx)
            shifts -= numpy.where(
                numpy.abs(pos_1[:, 0] - self.xmax) < prec,
                random * part_solver.pic.mesh.dx / 2, 0)
            pos_1[:, 0] += shifts
            hit_1 = numpy.zeros_like(pos_1[:, 1], dtype=numpy.uint8)[:, None]
        #Left
        elif self.directions[local_loc[0]] == 3:
            shifts = numpy.where(
                numpy.abs(pos_1[:, 1] - self.ymin) < prec,
                random * part_solver.pic.mesh.dy / 2,
                (random - 0.5) * part_solver.pic.mesh.dy)
            shifts -= numpy.where(
                numpy.abs(pos_1[:, 1] - self.ymax) < prec,
                random * part_solver.pic.mesh.dy / 2, 0)
            pos_1[:, 1] += shifts
            hit_1 = 3 * numpy.ones_like(pos_1[:, 1], dtype=numpy.uint8)[:,
                                                                        None]
        #Right
        elif self.directions[local_loc[0]] == 1:
            shifts = numpy.where(
                numpy.abs(pos_1[:, 1] - self.ymin) < prec,
                random * part_solver.pic.mesh.dy / 2,
                (random - 0.5) * part_solver.pic.mesh.dy)
            shifts -= numpy.where(
                numpy.abs(pos_1[:, 1] - self.ymax) < prec,
                random * part_solver.pic.mesh.dy / 2, 0)
            pos_1[:, 1] += shifts
            hit_1 = numpy.ones_like(pos_1[:, 1], dtype=numpy.uint8)[:, None]
        #Top
        else:
            shifts = numpy.where(
                numpy.abs(pos_1[:, 0] - self.xmin) < prec,
                random * part_solver.pic.mesh.dx / 2,
                (random - 0.5) * part_solver.pic.mesh.dx)
            shifts -= numpy.where(
                numpy.abs(pos_1[:, 0] - self.xmax) < prec,
                random * part_solver.pic.mesh.dx / 2, 0)
            pos_1[:, 0] += shifts
            hit_1 = 2 * numpy.ones_like(pos_1[:, 1], dtype=numpy.uint8)[:,
                                                                        None]

        repeats = numpy.ones(numpy.shape(hit_1)[0], dtype=numpy.uint8)
        return (numpy.append(pos_1, hit_1, axis=1), ), repeats