Пример #1
0
    def stress_bc_getter(self, init=False):
        """
        generate code for updating stress field boundary ghost cells
        - generate inner loop by inserting boundary code (saved in field.bc)
        - recursive insertion to generate nested loop
        - loop through all stress fields and sides
        - if init=True (initialisation), no need to generate code to overwrite Txx, Tyy, Tzz
        return generated code as string
        """
        result = []
        body = []
        if self.eval_const:
            self.create_const_dict()
        for field in self.sfields:
            # normal stress, not shear stress
            normal = field.direction[0] == field.direction[1]
            for d in range(self.dimension):
                if init and normal and (not field.direction[0] == d+1):
                    # skip re-calc Txx, Tyy at z plane etc, when initialisation
                    continue
                for side in range(2):
                    # skip if this boundary calculation is not needed
                    if field.bc[d+1][side] == []:
                        continue
                    if self.omp:
                        result += [cgen.Pragma('omp for schedule(static,1)')]
                    body = []
                    for d2 in range(self.dimension-1, -1, -1):
                        # loop through other dimensions
                        if not d2 == d:
                            i = self.index[d2]
                            if normal:
                                if field.direction[0] == d+1:
                                    # Txx in x plane
                                    i0 = 0
                                    i1 = self.dim[d2]
                                else:
                                    # Txx in y, z plane
                                    i0 = self.margin.value+1
                                    i1 = self.dim[d2]-self.margin.value-1
                            else:
                                i0 = 0
                                i1 = self.dim[d2]

                            if not body:
                                # inner loop, populate ghost cell calculation
                                bc_list = self.transform_bc(field, d+1, side)
                                if self.read:
                                    body = [cgen.Statement(ccode_eq(self.resolve_media_params(bc)).replace('[_t + 1]', '[_t1]').replace('[_t]', '[_t0]')) for bc in bc_list]
                                else:
                                    body = [cgen.Statement(ccode_eq(bc).replace('[_t + 1]', '[_t1]').replace('[_t]', '[_t0]')) for bc in bc_list]
                                body = [cgen.For(cgen.InlineInitializer(cgen.Value('int', i), i0), cgen.Line('%s<%s' % (i, i1)), cgen.Line('++%s' % i), cgen.Block(body))]
                                if self.ivdep:
                                    body.insert(0, self.compiler._ivdep)
                                if self.simd:
                                    body.insert(0, cgen.Pragma('simd'))
                            else:
                                body = [cgen.For(cgen.InlineInitializer(cgen.Value('int', i), i0), cgen.Line('%s<%s' % (i, i1)), cgen.Line('++%s' % i), cgen.Block(body))]
                    result += body
        return cgen.Module(result)
Пример #2
0
    def set_free_surface(self, indices, d, b, side, read=False):
        """
        set free surface boundary condition to boundary d, at index b
        :param indices: list of indices, e.g. [t,x,y,z] for 3D
        :param d: direction of the boundary surface normal
        :param b: location of the boundary (index)
        side: lower boundary (0) or upper boundary (1)
        e.g. set_free_surface([t,x,y,z],1,2,0)
        set y-z plane at x=2 to be lower free surface
        ghost cells are calculated using reflection of stress fields
        store the code to populate ghost cells to self.bc
        """
        if d not in self.direction:
            # e.g. x boundary for field Tyy is not required
            self.bc[d][side] = ''
            return

        idx = list(indices)  # ghost cell
        idx2 = list(indices)  # cell inside domain

        if not self.staggered[d]:
            # if not staggered, assign T[d]=0, assign T[d-1]=-T[d+1]
            idx[d] = b
            idx2[d] = b
            eq1 = Eq(self[idx])
        else:
            # if staggered, assign T[d-1/2]=T[d+1/2], assign T[d-3/2]=T[d+3/2]
            idx[d] = b - (1-side)
            idx2[d] = idx[d] + (-1)**side
            eq1 = Eq(self[idx], -self[idx2])

        idx[d] -= (-1)**side
        idx2[d] += (-1)**side
        eq2 = Eq(self[idx], -self[idx2])
        self.bc[d][side] = ccode_eq(eq1) + ';\n' + ccode_eq(eq2) + ';\n'
Пример #3
0
    def velocity_bc(self):
        """
        generate code for updating stress field boundary ghost cells
        - generate inner loop by inserting boundary code (saved in field.bc)
        - recursive insertion to generate nested loop
        - loop through all velocity fields and sides
        return generated code as string
        """
        result = []
        if self.eval_const:
            self.create_const_dict()
        for d in range(self.dimension):
            # update the staggered field first
            # because other fields depends on it
            sequence = [f for f in self.vfields if f.staggered[d+1]] \
                + [f for f in self.vfields if not f.staggered[d+1]]
            for field in sequence:
                for side in range(2):
                    # skip if this boundary calculation is not needed
                    if field.bc[d+1][side] == '':
                        continue
                    if self.omp:
                        result += [cgen.Pragma('omp for schedule(static,1)')]
                    body = []
                    for d2 in range(self.dimension-1, -1, -1):
                        # loop through other dimensions
                        if not d2 == d:
                            i = self.index[d2]
                            i0 = 1
                            i1 = self.dim[d2]-1
                            if not body:
                                # inner loop, populate ghost cell calculation
                                # body = field.bc[d+1][side]
                                bc_list = self.transform_bc(field, d+1, side)
                                if self.read:
                                    body = [cgen.Statement(ccode_eq(self.resolve_media_params(bc)).replace('[_t + 1]', '[_t1]').replace('[_t]', '[_t0]')) for bc in bc_list]
                                else:
                                    body = [cgen.Statement(ccode_eq(bc).replace('[_t + 1]', '[_t1]').replace('[_t]', '[_t0]')) for bc in bc_list]
                                body = [cgen.For(cgen.InlineInitializer(cgen.Value('int', i), i0), cgen.Line('%s<%s' % (i, i1)), cgen.Line('++%s' % i), cgen.Block(body))]
                                if self.ivdep:
                                    body.insert(0, self.compiler._ivdep)
                                if self.simd:
                                    body.insert(0, cgen.Pragma('simd'))
                            else:
                                body = [cgen.For(cgen.InlineInitializer(cgen.Value('int', i), i0), cgen.Line('%s<%s' % (i, i1)), cgen.Line('++%s' % i), cgen.Block(body))]

                    result += body

        return cgen.Module(result)