1# -*- coding: utf-8 -*- 2# 3# Copyright (C) 2015,20016 Thorsten Liebig (Thorsten.Liebig@gmx.de) 4# 5# This program is free software: you can redistribute it and/or modify 6# it under the terms of the GNU Lesser General Public License as published 7# by the Free Software Foundation, either version 3 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU Lesser General Public License for more details. 14# 15# You should have received a copy of the GNU Lesser General Public License 16# along with this program. If not, see <http://www.gnu.org/licenses/>. 17# 18 19""" 20Rectilinear Grid Class for CSXCAD 21""" 22 23import numpy as np 24cimport CSRectGrid 25from Utilities import CheckNyDir 26from CSXCAD.SmoothMeshLines import SmoothMeshLines 27 28cdef class CSRectGrid: 29 """ 30 Rectilinear Grid Class for CSXCAD. The grid can be defined e.g. as a Cartesian 31 or cylindrical mesh and can hold mesh lines in the 3 fundamental directions. 32 E.g. x,y and z for the Cartesian and rho, a and z for the cylindrical mesh. 33 34 :param CoordSystem: define the coordinate system (default 0 : Cartesian) 35 """ 36 def __cinit__(self, *args, no_init=False, **kw): 37 self.no_init = no_init 38 if no_init==False: 39 self.thisptr = new _CSRectGrid() 40 if 'CoordSystem' in kw: 41 self.SetMeshType(kw['CoordSystem']) 42 del kw['CoordSystem'] 43 elif 'cs_type' in kw: 44 self.SetMeshType(kw['cs_type']) 45 del kw['cs_type'] 46 else: 47 self.thisptr = NULL 48 49 assert len(kw)==0, 'Unknown keyword arguments: "{}"'.format(kw) 50 51 def __dealloc__(self): 52 if not self.no_init: 53 del self.thisptr 54 55 def SetMeshType(self, cs_type): 56 """ SetMeshType(cs_type) 57 58 Set the coordinate system type (Cartesian or cylindrical) for this mesh. 59 60 :param cs_type: coordinate system (0 : Cartesian, 1 : Cylindrical) 61 """ 62 assert cs_type in [CARTESIAN, CYLINDRICAL], 'Unknown coordinate system: {}'.format(cs_type) 63 self.thisptr.SetMeshType(cs_type) 64 65 def GetMeshType(self): 66 return self.thisptr.GetMeshType() 67 68 def SetLines(self, ny, lines): 69 """ SetLines(ny, lines) 70 71 Set an array of lines. This will clear all previous defined lines in 72 the given direction. 73 74 :param ny: int or str -- direction definition 75 :param lines: array -- list of lines to be set in the given direction 76 """ 77 ny = CheckNyDir(ny) 78 79 assert len(lines)>0, 'SetLines: "lines" must be an array or list' 80 self.thisptr.ClearLines(ny) 81 for n in range(len(lines)): 82 self.thisptr.AddDiscLine(ny, lines[n]) 83 84 def AddLine(self, ny, line): 85 """ AddLine(ny, lines) 86 87 Add an array of lines. This will *not* clear the previous defined lines in 88 the given direction. 89 90 :param ny: int or str -- direction definition 91 :param lines: array -- list of lines to be added in the given direction 92 """ 93 ny = CheckNyDir(ny) 94 if np.isscalar(line): 95 self.thisptr.AddDiscLine(ny, line) 96 return 97 assert len(line)>0, 'AddLine: "lines" must be a float, array or list' 98 for n in range(len(line)): 99 self.thisptr.AddDiscLine(ny, line[n]) 100 101 def GetQtyLines(self, ny): 102 """ GetQtyLines(ny) 103 104 :param ny: int or str -- direction definition 105 """ 106 ny = CheckNyDir(ny) 107 return self.thisptr.GetQtyLines(ny) 108 109 def GetLine(self, ny, idx): 110 """ GetLine(ny, idx) 111 112 Get the line in a given direction `ny` and index 113 114 :param ny: int or str -- direction definition 115 :param idx: int -- line index 116 """ 117 ny = CheckNyDir(ny) 118 return self.thisptr.GetLine(ny, idx) 119 120 def GetLines(self, ny, do_sort=False): 121 """ GetLines(ny, do_sort=False) 122 123 Get all lines in a given direction `ny`. 124 125 :param ny: int or str -- direction definition 126 :param do_sort: bool -- sort lines 127 """ 128 ny = CheckNyDir(ny) 129 cdef unsigned int N = 0 130 cdef double* array = NULL 131 array = self.thisptr.GetLines(ny, array, N, do_sort) 132 lines = np.zeros(N) 133 for n in range(N): 134 lines[n] = array[n] 135 return lines 136 137 def ClearLines(self, ny): 138 """ ClearLines(ny) 139 140 Clear all lines in a given direction `ny`. 141 142 :param ny: int or str -- direction definition 143 """ 144 ny = CheckNyDir(ny) 145 self.thisptr.ClearLines(ny) 146 147 def SmoothMeshLines(self, ny, max_res, ratio=1.5): 148 """ SmoothMeshLines(ny, max_res, ratio=1.5) 149 150 Smooth all mesh lines in the given direction with a max. allowed resolution. 151 152 :param ny: int or str -- direction definition or 'all' for all directions 153 :param max_res: float -- max. allowed resolution 154 :param ratio: float -- max. allowed ration of mesh smoothing de/increase 155 """ 156 if ny=='all': 157 for n in range(3): 158 self.SmoothMeshLines(n, max_res, ratio) 159 else: 160 lines = self.GetLines(ny) 161 lines = SmoothMeshLines(lines, max_res, ratio) 162 self.SetLines(ny, lines) 163 164 def Clear(self): 165 """ 166 Clear all lines and delta unit. 167 """ 168 self.thisptr.clear() 169 170 def SetDeltaUnit(self, unit): 171 """ SetDeltaUnit(unit) 172 173 Set the drawing unit for all mesh lines. Default is 1 (m) 174 """ 175 self.thisptr.SetDeltaUnit(unit) 176 177 def GetDeltaUnit(self): 178 """ 179 Get the drawing unit for all mesh lines. 180 """ 181 return self.thisptr.GetDeltaUnit() 182 183 def Sort(self, ny='all'): 184 """ Sort(ny='all') 185 186 Sort mesh lines in the given direction or all directions. 187 """ 188 if ny=='all': 189 for n in range(3): 190 self.thisptr.Sort(n) 191 else: 192 ny = CheckNyDir(ny) 193 self.thisptr.Sort(ny) 194 195 def Snap2LineNumber(self, ny, value): 196 """ Snap2LineNumber(ny, value) 197 198 Find a fitting mesh line index for the given direction and value. 199 """ 200 ny = CheckNyDir(ny) 201 cdef bool inside=False 202 pos = self.thisptr.Snap2LineNumber(ny, value, inside) 203 return pos, inside>0 204 205 def GetSimArea(self): 206 """ 207 Get the simulation area as defined by the mesh. 208 209 :returns: (2,3) array -- Simulation domain box 210 """ 211 bb = np.zeros([2,3]) 212 cdef double *_bb = self.thisptr.GetSimArea() 213 for n in range(3): 214 bb[0,n] = _bb[2*n] 215 bb[1,n] = _bb[2*n+1] 216 return bb 217 218 def IsValid(self): 219 """ 220 Check if the mesh is valid. That is at least 2 mesh lines in all directions. 221 """ 222 return self.thisptr.isValid() 223