summaryrefslogtreecommitdiff
path: root/CSXCAD/python/CSXCAD/CSRectGrid.pyx
blob: d47467b580f54c5889374357037236b65bfc54b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# -*- coding: utf-8 -*-
#
# Copyright (C) 2015,20016 Thorsten Liebig (Thorsten.Liebig@gmx.de)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

"""
Rectilinear Grid Class for CSXCAD
"""

import numpy as np
cimport CSRectGrid
from Utilities import CheckNyDir
from SmoothMeshLines import SmoothMeshLines

cdef class CSRectGrid:
    """
    Rectilinear Grid Class for CSXCAD. The grid can be defined e.g. as a Cartesian
    or cylindrical mesh and can hold mesh lines in the 3 fundamental directions.
    E.g. x,y and z for the Cartesian and rho, a and z for the cylindrical mesh.

    :param CoordSystem: define the coordinate system (default 0 : Cartesian)
    """
    def __cinit__(self, *args, no_init=False, **kw):
        self.no_init = no_init
        if no_init==False:
            self.thisptr = new _CSRectGrid()
            if 'CoordSystem' in kw:
                self.SetMeshType(kw['CoordSystem'])
                del kw['CoordSystem']
            elif 'cs_type' in kw:
                self.SetMeshType(kw['cs_type'])
                del kw['cs_type']
        else:
            self.thisptr = NULL

        assert len(kw)==0, 'Unknown keyword arguments: "{}"'.format(kw)

    def __dealloc__(self):
        if not self.no_init:
            del self.thisptr

    def SetMeshType(self, cs_type):
        """ SetMeshType(cs_type)

        Set the coordinate system type (Cartesian or cylindrical) for this mesh.

        :param cs_type: coordinate system (0 : Cartesian, 1 : Cylindrical)
        """
        assert cs_type in [CARTESIAN, CYLINDRICAL], 'Unknown coordinate system: {}'.format(cs_type)
        self.thisptr.SetMeshType(cs_type)

    def GetMeshType(self):
        return self.thisptr.GetMeshType()

    def SetLines(self, ny, lines):
        """ SetLines(ny, lines)

        Set an array of lines. This will clear all previous defined lines in
        the given direction.

        :param ny: int or str -- direction definition
        :param lines: array -- list of lines to be set in the given direction
        """
        ny = CheckNyDir(ny)

        assert len(lines)>0, 'SetLines: "lines" must be an array or list'
        self.thisptr.ClearLines(ny)
        for n in range(len(lines)):
            self.thisptr.AddDiscLine(ny, lines[n])

    def AddLine(self, ny, line):
        """ AddLine(ny, lines)

        Add an array of lines. This will *not* clear the previous defined lines in
        the given direction.

        :param ny: int or str -- direction definition
        :param lines: array -- list of lines to be added in the given direction
        """
        ny = CheckNyDir(ny)
        if np.isscalar(line):
            self.thisptr.AddDiscLine(ny, line)
            return
        assert len(line)>0, 'AddLine: "lines" must be a float, array or list'
        for n in range(len(line)):
            self.thisptr.AddDiscLine(ny, line[n])

    def GetQtyLines(self, ny):
        """ GetQtyLines(ny)

        :param ny: int or str -- direction definition
        """
        ny = CheckNyDir(ny)
        return self.thisptr.GetQtyLines(ny)

    def GetLine(self, ny, idx):
        """ GetLine(ny, idx)

        Get the line in a given direction `ny` and index

        :param ny: int or str -- direction definition
        :param idx: int  -- line index
        """
        ny = CheckNyDir(ny)
        return self.thisptr.GetLine(ny, idx)

    def GetLines(self, ny, do_sort=False):
        """ GetLines(ny, do_sort=False)

        Get all lines in a given direction `ny`.

        :param ny: int or str -- direction definition
        :param do_sort: bool  -- sort lines
        """
        ny = CheckNyDir(ny)
        cdef unsigned int N = 0
        cdef double* array = NULL
        array = self.thisptr.GetLines(ny, array, N, do_sort)
        lines = np.zeros(N)
        for n in range(N):
            lines[n] = array[n]
        return lines

    def ClearLines(self, ny):
        """ ClearLines(ny)

        Clear all lines in a given direction `ny`.

        :param ny: int or str -- direction definition
        """
        ny = CheckNyDir(ny)
        self.thisptr.ClearLines(ny)

    def SmoothMeshLines(self, ny, max_res, ratio=1.5):
        """ SmoothMeshLines(ny, max_res, ratio=1.5)

        Smooth all mesh lines in the given direction with a max. allowed resolution.

        :param ny: int or str -- direction definition or 'all' for all directions
        :param max_res: float -- max. allowed resolution
        :param ratio:   float -- max. allowed ration of mesh smoothing de/increase
        """
        if ny=='all':
            for n in range(3):
                self.SmoothMeshLines(n, max_res, ratio)
        else:
            lines = self.GetLines(ny)
            lines = SmoothMeshLines(lines, max_res, ratio)
            self.SetLines(ny, lines)

    def Clear(self):
        """
        Clear all lines and delta unit.
        """
        self.thisptr.clear()

    def SetDeltaUnit(self, unit):
        """ SetDeltaUnit(unit)

        Set the drawing unit for all mesh lines. Default is 1 (m)
        """
        self.thisptr.SetDeltaUnit(unit)

    def GetDeltaUnit(self):
        """
        Get the drawing unit for all mesh lines.
        """
        return self.thisptr.GetDeltaUnit()

    def Sort(self, ny='all'):
        """ Sort(ny='all')

        Sort mesh lines in the given direction or all directions.
        """
        if ny=='all':
            for n in range(3):
                self.thisptr.Sort(n)
        else:
            ny = CheckNyDir(ny)
            self.thisptr.Sort(ny)

    def Snap2LineNumber(self, ny, value):
        """ Snap2LineNumber(ny, value)

        Find a fitting mesh line index for the given direction and value.
        """
        ny = CheckNyDir(ny)
        cdef bool inside=False
        pos = self.thisptr.Snap2LineNumber(ny, value, inside)
        return pos, inside>0

    def GetSimArea(self):
        """
        Get the simulation area as defined by the mesh.

        :returns: (2,3) array -- Simulation domain box
        """
        bb = np.zeros([2,3])
        cdef double *_bb = self.thisptr.GetSimArea()
        for n in range(3):
            bb[0,n] = _bb[2*n]
            bb[1,n] = _bb[2*n+1]
        return bb

    def IsValid(self):
        """
        Check if the mesh is valid. That is at least 2 mesh lines in all directions.
        """
        return self.thisptr.isValid()