'잡동사니'에 해당되는 글 13032건
- 2023.05.28 비
- 2023.05.27 fftw 다차원 분석
- 2023.05.26 rust mut 외 몇가지 컴파일 에러들
- 2023.05.26 nxp i.mx8mp win iot part 2
- 2023.05.26 nxp i.mx8mp win iot
- 2023.05.25 rust mut
- 2023.05.25 rust visibility and privacy
- 2023.05.25 cobs
- 2023.05.25 rust 소유권
- 2023.05.24 openFOAM tutorial with youtube
libttfw 에서는 2차원 3차원 DFT를 지원하는데, 내가 생각하는 그 2차원 3차원이 맞나 모르겠다.
센서가 3축이면 3차원은 맞긴한데.. 희소행렬 형태로 삽입이 되어야 하나?
2.2 Complex Multi-Dimensional DFTs Multi-dimensional transforms work much the same way as one-dimensional transforms: you allocate arrays of fftw_complex (preferably using fftw_malloc), create an fftw_plan, execute it as many times as you want with fftw_execute(plan), and clean up with fftw_destroy_plan(plan) (and fftw_free). FFTW provides two routines for creating plans for 2d and 3d transforms, and one routine for creating plans of arbitrary dimensionality. The 2d and 3d routines have the following signature: fftw_plan fftw_plan_dft_2d(int n0, int n1, fftw_complex *in, fftw_complex *out, int sign, unsigned flags); fftw_plan fftw_plan_dft_3d(int n0, int n1, int n2, fftw_complex *in, fftw_complex *out, int sign, unsigned flags); |
[링크 : https://www.fftw.org/fftw3_doc/Complex-Multi_002dDimensional-DFTs.html]
3.2.1 Row-major Format The multi-dimensional arrays passed to fftw_plan_dft etcetera are expected to be stored as a single contiguous block in row-major order (sometimes called “C order”). Basically, this means that as you step through adjacent memory locations, the first dimension’s index varies most slowly and the last dimension’s index varies most quickly. To be more explicit, let us consider an array of rank d whose dimensions are n0 × n1 × n2 × … × nd-1 . Now, we specify a location in the array by a sequence of d (zero-based) indices, one for each dimension: (i0, i1, i2,..., id-1). If the array is stored in row-major order, then this element is located at the position id-1 + nd-1 * (id-2 + nd-2 * (... + n1 * i0)). Note that, for the ordinary complex DFT, each element of the array must be of type fftw_complex; i.e. a (real, imaginary) pair of (double-precision) numbers. In the advanced FFTW interface, the physical dimensions n from which the indices are computed can be different from (larger than) the logical dimensions of the transform to be computed, in order to transform a subset of a larger array. Note also that, in the advanced interface, the expression above is multiplied by a stride to get the actual array index—this is useful in situations where each element of the multi-dimensional array is actually a data structure (or another array), and you just want to transform a single field. In the basic interface, however, the stride is 1. |
[링크 : https://www.fftw.org/fftw3_doc/Row_002dmajor-Format.html]
A multi-dimensional array whose size is declared at compile time in C is already in row-major order. You don’t have to do anything special to transform it. For example: { fftw_complex data[N0][N1][N2]; fftw_plan plan; ... plan = fftw_plan_dft_3d(N0, N1, N2, &data[0][0][0], &data[0][0][0], FFTW_FORWARD, FFTW_ESTIMATE); ... } This will plan a 3d in-place transform of size N0 x N1 x N2. Notice how we took the address of the zero-th element to pass to the planner (we could also have used a typecast). |
[링크 : https://www.fftw.org/fftw3_doc/Fixed_002dsize-Arrays-in-C.html]
[링크 : https://www.fftw.org/fftw3_doc/Multi_002ddimensional-Array-Format.html]
+
에라이 모르겠다 ㅠㅠ
switch (sz->rnk) { case 1: if (p->sign < 0) { if (verbose > 2) printf("using plan_dft_r2c_1d\n"); return FFTW(plan_dft_r2c_1d)(sz->dims[0].n, (bench_real *) p->in, (bench_complex *) p->out, flags); } else { if (verbose > 2) printf("using plan_dft_c2r_1d\n"); return FFTW(plan_dft_c2r_1d)(sz->dims[0].n, (bench_complex *) p->in, (bench_real *) p->out, flags); } break; case 2: if (p->sign < 0) { if (verbose > 2) printf("using plan_dft_r2c_2d\n"); return FFTW(plan_dft_r2c_2d)(sz->dims[0].n, sz->dims[1].n, (bench_real *) p->in, (bench_complex *) p->out, flags); } else { if (verbose > 2) printf("using plan_dft_c2r_2d\n"); return FFTW(plan_dft_c2r_2d)(sz->dims[0].n, sz->dims[1].n, (bench_complex *) p->in, (bench_real *) p->out, flags); } break; case 3: if (p->sign < 0) { if (verbose > 2) printf("using plan_dft_r2c_3d\n"); return FFTW(plan_dft_r2c_3d)( sz->dims[0].n, sz->dims[1].n, sz->dims[2].n, (bench_real *) p->in, (bench_complex *) p->out, flags); } else { if (verbose > 2) printf("using plan_dft_c2r_3d\n"); return FFTW(plan_dft_c2r_3d)( sz->dims[0].n, sz->dims[1].n, sz->dims[2].n, (bench_complex *) p->in, (bench_real *) p->out, flags); } break; default: { int *n = mkn(sz); if (p->sign < 0) { if (verbose > 2) printf("using plan_dft_r2c\n"); pln = FFTW(plan_dft_r2c)(sz->rnk, n, (bench_real *) p->in, (bench_complex *) p->out, flags); } else { if (verbose > 2) printf("using plan_dft_c2r\n"); pln = FFTW(plan_dft_c2r)(sz->rnk, n, (bench_complex *) p->in, (bench_real *) p->out, flags); } bench_free(n); return pln; } } |
[링크 : https://github.com/FFTW/fftw3/blob/master/tests/bench.c]
+
mpi 예제도 있음.
그런데 3d로 한다고 하니 어마어마하게 데이터가 필요할 것 같은데
단순하게 3축 데이터라면 엄청 큰 공간에 딱 3줄 넣는 식이 될텐데 어떻게 해야 할까?
data = (FFTW_COMPLEX *) FFTW_MALLOC(sizeof(FFTW_COMPLEX) * NX*NY*NZ*sizeof(FFTW_COMPLEX)); /* create plan for forward DFT */ gettimeofday(&tv_start, NULL); plan = FFTW_PLAN_DFT_3D(NX, NY, NZ, data, data, FFTW_FORWARD, FFTW_ESTIMATE); gettimeofday(&tv_stop, NULL); deltaT = tv_stop.tv_sec - tv_start.tv_sec + 1e-6 * (tv_stop.tv_usec - tv_start.tv_usec); printf("Plan init time (c2c) : %f sec\n", deltaT); /* initialize data */ for (i = 0; i < NX; ++i) { for (j = 0; j < NY; ++j) { for (k = 0; k < NZ; ++k) { data[(i*NY + j)*NZ + k][0] = (i*NY + j)*NZ + k; data[(i*NY + j)*NZ + k][1] = 0; } } } |
[링크 : https://github.com/pkestene/simpleFFTW/blob/master/c/fftw_test_3d_serial.c]
+
암만봐도 2d나 3d fft는 어떻게 써야 할지 감도 안와서 사용 시도 자체를 포기!
'프로그램 사용 > fft, fftw' 카테고리의 다른 글
fft 잘못 사용하고 있었나? (0) | 2023.06.02 |
---|---|
fft 라이브러리 목록 (0) | 2023.06.01 |
fft phase 연산 (0) | 2023.04.07 |
fftw input range? (0) | 2023.04.07 |
fft 복소수(complex) - 실수, 허수부(real, imaginary) (0) | 2023.04.07 |
use std::io; 없이 사용시
error[E0433]: failed to resolve: use of undeclared crate or module `io` --> main.rs:8:5 | 8 | io::stdin() | ^^ | | | use of undeclared crate or module `io` | help: a builtin type with a similar name exists: `i8` error: aborting due to previous error For more information about this error, try `rustc --explain E0433`. |
변수 사용 없음 (경고)
warning: unused `Result` that must be used --> main.rs:10:5 | 10 | / io::stdin() 11 | | .read_line(&mut guess); | |______________________________^ | = note: this `Result` may be an `Err` variant, which should be handled = note: `#[warn(unused_must_use)]` on by default warning: 1 warning emitted |
read_line mut 없이
error[E0308]: mismatched types --> main.rs:11:20 | 11 | .read_line(&guess); | --------- ^^^^^^ types differ in mutability | | | arguments to this method are incorrect | = note: expected mutable reference `&mut String` found reference `&String` note: method defined here --> /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc\library\std\src\io\stdio.rs:383:12 error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. |
///
let guess = String::new();
io::stdin().read_line(&mut guess);
///
error[E0596]: cannot borrow `guess` as mutable, as it is not declared as mutable --> main.rs:11:20 | 11 | .read_line(&mut guess); | ^^^^^^^^^^ cannot borrow as mutable | help: consider changing this to be mutable | 8 | let mut guess = String::new(); | +++ error: aborting due to previous error For more information about this error, try `rustc --explain E0596`. |
//
let guess = String::new();
io::stdin().read_line(&guess);
//
error[E0308]: mismatched types --> main.rs:9:27 | 9 | io::stdin().read_line(&guess); | --------- ^^^^^^ types differ in mutability | | | arguments to this method are incorrect | = note: expected mutable reference `&mut String` found reference `&String` note: method defined here --> /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc\library\std\src\io\stdio.rs:383:12 error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. |
'Programming > rust' 카테고리의 다른 글
rust mut (0) | 2023.05.25 |
---|---|
rust visibility and privacy (0) | 2023.05.25 |
rust 소유권 (0) | 2023.05.25 |
rust was (0) | 2023.05.20 |
c에서 rust 호출하기 (0) | 2023.05.11 |
다시 문서를 보니 이전에 10.1 단계를 건너뛰고 10.2만 진행한 것 같다.
아무생각 없이 무지성으로 win 10 x64용 에서 해당 파일 꺼내려고 보니 2GB.
아키텍쳐가 안되겠지...? 라는 생각에
win 10 iot ent 다운로드 받는데 4시간..(32bit / 64bit + 영어 / 국문...)
10.1 Flashing Windows 10 IoT Installer to the SD card Currently, the only way to deploy a Windows IoT Enterprise on the onboard eMMC is to use WinPE. OS (Windows Preinstallation Environment) to write the Windows IoT image to eMMC. Windows manufacturing OS (WinPE) that can be fully loaded and run from memory without using persistent storage. The following steps create an SD card with WinPE and a Windows IoT image that contains the BSP drivers. The boot firmware checks the SD card and boots WinPE, which then installs the Windows IoT image to the eMMC. 1. Decompress the W21H2-1-x-x-imx-windows-bsp-binaries.zip file. The package contains release-signed prebuilt binaries and image files. 2. Open the elevated command prompt and navigate to the IoTEntOnNXP directory. 3. Mount the previously downloaded Windows IoT Enterprise ISO image file (see chapter Software requirements) and copy the install.wim file from the <DVD mount drive:>\sources\install.wim to the IoTEntOnNXP directory. 4. Execute the command: make-winpe-enterprise.cmd /disable_updates /disable_transparency /test_signing This command creates a copy of the selected install.wim image with injected i.MX drivers and applied updates from the kbpatch/ directory. These patches are for Windows 21H2, build 19044.1288 and update the image to build 19044.2566. Note: Be sure to copy the whole command line. 5. Execute the command: make-winpe-enterprise.cmd /apply <disk_number> where <disk_number> is the physical number of the SD card disk on your PC. It can be obtained using the Disk Management tool (right-click the start menu icon and select Disk Management). This command deploys the WinPE image to the SD card. CAUTION: Make sure to select the correct disk number, as this step formats the selected disk! The WinPEbased Windows installer is now deployed on the SD card. 6. Continue with the firmware installation to the SD card. 10.2 Flashing firmware to the SD card During active development of the boot firmware, it can be time-consuming and error-prone to repeatedly change the dip switches between UUU download mode and eMMC boot mode. To simplify this process, the i.MX EVK boards support SD card boot mode that allows you to keep the boot firmware on an SD card. To deploy boot firmware to an SD card from Windows, we recommend using the Cfimager tool from https://www. nxp.com/webapp/Download?colCode=CF_IMAGER. Perform the following steps to flash the firmware to the SD card: 1. Download the NXP cfimager tool and copy it into the firmware directory or a directory listed in the system environment variable %PATH%. 2. Navigate to the firmware directory. 3. Plug the SD card into the host PC and execute the following board-specific command: For i.MX 8M Mini EVK board: flash_bootloader.cmd /device MX8M_MINI_EVK /target_drive <SD card driver letter, for example, f:> For i.MX 8M Quad EVK board: flash_bootloader.cmd /device MX8M_EVK /target_drive <SD card driver letter, for example, f:> For i.MX 8M Nano EVK board: flash_bootloader.cmd /device MX8M_NANO_EVK /target_drive <SD card driver letter, for example, f:> For i.MX 8M Plus EVK board: flash_bootloader.cmd /device MX8M_PLUS_EVK /target_drive <SD card driver letter, for example, f:> For i.MX 8QuadXPlus MEK board: flash_bootloader.cmd /device MX8QXP_MEK /target_drive <SD card driver letter, for example, f:> For i.MX 93 EVK board: flash_bootloader.cmd /device MX93_11X11_EVK /target_drive <SD card driver letter, for example, f:> 4. Power off the board. 5. Insert the SD card to the board. 6. Change the boot device to the SD card. 7. Power on the board |
[링크 : https://www.nxp.com/docs/en/quick-reference-guide/IMXWQSG.pdf]
+
다시 시도 하는데 이런저런 또 막히는 것들 산더미 -_-
C:\nxp\W21H2-1-3-0-imx-windows-bsp-binaries\IoTEntOnNXP>make-winpe-enterprise.cmd /disable_updates /disable_transparency /test_signing You must install the Windows PE Add-on for the ADK https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/download-winpe--windows-pe Script failed Cleaning up 배포 이미지 서비스 및 관리 도구 버전: 10.0.22621.1 오류: 50 지원되지 않는 요청입니다. DISM 로그 파일은 C:\Windows\Logs\DISM\dism.log에 있습니다. 배포 이미지 서비스 및 관리 도구 버전: 10.0.22621.1 오류: 50 지원되지 않는 요청입니다. DISM 로그 파일은 C:\Windows\Logs\DISM\dism.log에 있습니다. C:\nxp\W21H2-1-3-0-imx-windows-bsp-binaries\IoTEntOnNXP\diskpart.txt을(를) 찾을 수 없습니다. |
그래서 PE Addon 만 까는 청개구리 짓을 발동!
다시 문서를 읽어 보니 adk for win10, winpe addon for adk 2004 두개를 깔아야 한다고 한데 winPE add-on for ADK 만 설치해도 일단은 넘어간다.
3 Software requirements • Binary drivers and firmware (either downloaded from nxp.com or built locally) • Windows IoT operating system. There are two options: – Visual Studio Subscription portal my.visualstudio.com – At the portal, click Downloads -> Windows 10 -> Search for “Windows 10 IoT Enterprise LTSC 2021” or “Windows 10 IoT Enterprise 2021” – The default architecture is set to x64, click the dropdown menu to change it to Arm64 and download the DVD – Through microsoftoem.com facilitated by a Windows IoT OS distributor – To find a distributor, visit aka.ms/iotdistributorlist • Windows ADK for Windows 10 and Windows PE add-on for ADK, version 2004. |
다시 시도하니 되는것 같긴한데
무지성으로(!) 받은 x86 , x64용 Win IoT Ent 라서 ARM64 아니라고 뱉는다.
C:\nxp\W21H2-1-3-0-imx-windows-bsp-binaries\IoTEntOnNXP>make-winpe-enterprise.cmd /disable_updates /disable_transparency /test_signing Selected: "install.wim" Source image: install.wim Test signing: yes Patch Sdport: no Windows debug over ethernet: no, IP: Windows PE debug over ethernet: no, IP: KD_NET file (for debug over net): no Windows debug over serial: no Windows PE debug over serial: no Unattended install answer file: no Disable updates: yes Disable transparency: yes Split wim: no Cummulative update: no, path: ********************************************************************************************************************************************************* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *** Step 1 Creating i.MX Windows IoT Enterprise image: out\imx_win_iot_install.wim ********************************************************************************************************************************************************* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Cleaning up from previous run --------------------------------------------------------------------------------------------------------------------------------------------------------- *** Step 1.1 Copying Windows Enterprise image install.wim to out\imx_win_iot_install.wim --------------------------------------------------------------------------------------------------------------------------------------------------------- 하위 디렉터리 또는 파일 out이(가) 이미 있습니다. copy "install.wim" "out\imx_win_iot_install.wim" 1개 파일이 복사되었습니다. --------------------------------------------------------------------------------------------------------------------------------------------------------- *** Step 1.2 Mounting i.MX Windows IoT Enterprise image at out\mount_enterprise --------------------------------------------------------------------------------------------------------------------------------------------------------- dism /mount-wim /wimfile:"out\imx_win_iot_install.wim" /mountdir:"out\mount_enterprise" /index:2 배포 이미지 서비스 및 관리 도구 버전: 10.0.22621.1 오류: 0xc1510113 지정한 이미지가 WIM에 없습니다. WIM에서 먼저 기존 이미지가 있는지 확인하십시오. DISM 로그 파일은 C:\Windows\Logs\DISM\dism.log에 있습니다. |
'embeded > i.mx 8m plus' 카테고리의 다른 글
NXP i.mx8mp LF_v6.1.55-2.2.0 테스트 (0) | 2023.12.21 |
---|---|
missed: not vectorized: relevant stmt not supported: (0) | 2023.08.31 |
nxp i.mx8mp win iot (0) | 2023.05.26 |
rpmsg-lite (0) | 2023.03.23 |
i.mx8m plus cortex-m7 part.2 (0) | 2023.02.23 |
baudrate 보소.. 이런 변태 같은 -_-
3.1 Serial logging setup To help troubleshoot issues during boot, use the USB micro-B port on i.MX EVK boards to output U-Boot and UEFI firmware serial debug logs to a host PC. The USB micro-B port on the EVK presents a virtual serial port to the host PC, which can be read by common Windows serial terminal applications such as HyperTerminal, Tera Term, or PuTTY. 1. Connect the target and the PC using the cable mentioned above. 2. Open Device Manager on the PC and locate the Enhanced Virtual serial device and note the COM port number. 3. Open the terminal on the PC. Configure the Enhanced Virtual serial/COM port to 921600 baud/s, 8-bit, onestop bit. |
[링크 : https://www.nxp.com/docs/en/quick-reference-guide/IMXWQSG.pdf]
아무튼 baudrate 맞추니 이상하게 라도 나온다(키보드 인식 안해서 uart를 통해서 제어해야 하다니 -_ㅠ)
Device manager 뜨는게 없다.
Boot Manager 에서는 UEFI 옵션별로 뜨는데
요건 i.mx8mp 보드의 eMMC로 부팅하는거. 어떤 버전이 구워져있는진 모르겠지만
부팅하다가 kernel panic 뜨는데 어쩌면 윈도우용으로 부트로더가 설정하는 바람에
uboot + kernel 에서 설정되지 않는 부분때문에 그런걸지도 모르겠다.
윈도우 IoT 이미지가 2.5MB 밖에 안되서 그런가 SD 카드로 부팅하려고 하면 진행이 안된다.
Boot Maintenance Manager 에서는 먼가 조금 뜨는데 들어간다고 먼가 되는게 있는 것도 아니라서..
그나마 console option 으로 들어가면 input / output / stderr 요런걸로 어떤 장치를 쓸거냐 정도만 나온다.
그냥 윈도우 처럼 GUI 화면은 도대체 어떻게 해야 하냐..
'embeded > i.mx 8m plus' 카테고리의 다른 글
missed: not vectorized: relevant stmt not supported: (0) | 2023.08.31 |
---|---|
nxp i.mx8mp win iot part 2 (0) | 2023.05.26 |
rpmsg-lite (0) | 2023.03.23 |
i.mx8m plus cortex-m7 part.2 (0) | 2023.02.23 |
i.mx8m plus cortex-m7 (0) | 2023.02.23 |
변수에 값을 넣으면 c 처럼 값이 변경되지 않아
let을 이용 재귀적으로 다시 할당을 하거나 mut 키워드로 변경이 가능한 변수로 지정해야 한다.
fn main() { let x = 5; println!("The value of x is: {x}"); x = 6; println!("The value of x is: {x}"); } $ cargo run Compiling variables v0.1.0 (file:///projects/variables) error[E0384]: cannot assign twice to immutable variable `x` --> src/main.rs:4:5 | 2 | let x = 5; | - | | | first assignment to `x` | help: consider making this binding mutable: `mut x` 3 | println!("The value of x is: {x}"); 4 | x = 6; | ^^^^^ cannot assign twice to immutable variable For more information about this error, try `rustc --explain E0384`. error: could not compile `variables` due to previous error |
좀 더 아래 shadowing 에 있는 예제인데
let x = 5;
let x = x + 1; 을 이용해서 자기 자신에게 새로운 값을 소유하게 하는 것은 인정 되는 듯
fn main() { let x = 5; let x = x + 1; { let x = x * 2; println!("The value of x in the inner scope is: {x}"); } println!("The value of x is: {x}"); } |
아무튼 언어 설계상 정석은 mut 키워드를 쓰는 것으로 보인다.
fn main() { let mut x = 5; println!("The value of x is: {x}"); x = 6; println!("The value of x is: {x}"); } |
[링크 : https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html]
'Programming > rust' 카테고리의 다른 글
rust mut 외 몇가지 컴파일 에러들 (0) | 2023.05.26 |
---|---|
rust visibility and privacy (0) | 2023.05.25 |
rust 소유권 (0) | 2023.05.25 |
rust was (0) | 2023.05.20 |
c에서 rust 호출하기 (0) | 2023.05.11 |
pub 이라는 키워드가 존재해서
Syntax Visibility : pub | pub ( crate ) | pub ( self ) | pub ( super ) | pub ( in SimplePath ) |
기본은 private 이고 public으로 할 녀석들만 pub로 해주면 된다.
그런데 rust는 객체지향 언어는 아니라니까 class가 존재하지 않는데
c언어 처럼 static 키워드로 내/외부용으로 구분하는 수준이 되려나?
구조체에서 개별 항목에 대해서 pub이 적용되는지 조금 더 찾아봐야 할 것 같다.
// Declare a private struct struct Foo; // Declare a public struct with a private field pub struct Bar { field: i32, } // Declare a public enum with two public variants pub enum State { PubliclyAccessibleState, PubliclyAccessibleState2, } |
[링크 : https://doc.rust-lang.org/reference/visibility-and-privacy.html]
'Programming > rust' 카테고리의 다른 글
rust mut 외 몇가지 컴파일 에러들 (0) | 2023.05.26 |
---|---|
rust mut (0) | 2023.05.25 |
rust 소유권 (0) | 2023.05.25 |
rust was (0) | 2023.05.20 |
c에서 rust 호출하기 (0) | 2023.05.11 |
bit stuffing 등을 포함하는 상위개념
[링크 : https://en.m.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing]
'이론 관련 > 네트워크 관련' 카테고리의 다른 글
can invader (0) | 2024.01.09 |
---|---|
multicast (0) | 2023.08.26 |
PAM4 (0) | 2023.01.16 |
nrz encoding/decoding (0) | 2022.08.24 |
광 케이블 DAC, AOC (0) | 2022.06.30 |
rust에 추가된 개념으로 변수의 소유권 이라는 것이 있다.
좀 더 봐야 하지만, stack에 저장되는 경우에는 적용이 되지 않고 heap에 저장되는 변수들에 대해서 적용 될 것으로 예상된다.
변수 타입중 primitive와는 연관이 없을 것 같긴하다.
[링크 : https://doc.rust-lang.org/book/ch03-02-data-types.html]
소유자는 하나이다. 이게 포인트
Ownership Rules First, let’s take a look at the ownership rules. Keep these rules in mind as we work through the examples that illustrate them: Each value in Rust has an owner. There can only be one owner at a time. When the owner goes out of scope, the value will be dropped. |
primitive 타입이라 그런건지 아니면 heap이 아닌 stack에 생성되는 변수이기 때문인진 좀 더 봐야 하지만
x = 5; y = x;의 경우에는 5의 소유권이 x에 있지만 y = x를 통해 x가 지닌 5의 소유권이 y에게로 가는 것으로 보이진 않는다.
Variables and Data Interacting with Move Multiple variables can interact with the same data in different ways in Rust. Let’s look at an example using an integer in Listing 4-2. let x = 5; let y = x; Listing 4-2: Assigning the integer value of variable x to y We can probably guess what this is doing: “bind the value 5 to x; then make a copy of the value in x and bind it to y.” We now have two variables, x and y, and both equal 5. This is indeed what is happening, because integers are simple values with a known, fixed size, and these two 5 values are pushed onto the stack. Now let’s look at the String version: let s1 = String::from("hello"); let s2 = s1; This looks very similar, so we might assume that the way it works would be the same: that is, the second line would make a copy of the value in s1 and bind it to s2. But this isn’t quite what happens. |
간단(?)하게 생각하면 중괄호 끝날때가 scope의 끝이고
(사용자에게 보이진 않지만) 그때 마다 drop 함수가 호출되고 메모리 관리가 수행되는 것으로 생각된다.
그리고 이 때 소유권에 따라 사용되지 않는 변수는 사라지게 된다.
There is a natural point at which we can return the memory our String needs to the allocator: when s goes out of scope. When a variable goes out of scope, Rust calls a special function for us. This function is called drop, and it’s where the author of String can put the code to return the memory. Rust calls drop automatically at the closing curly bracket. Note: In C++, this pattern of deallocating resources at the end of an item’s lifetime is sometimes called Resource Acquisition Is Initialization (RAII). The drop function in Rust will be familiar to you if you’ve used RAII patterns. |
간단하게 생각하면... 메모리 포인터에 대해서 언어 레벨에서 관리하여
동일 포인터를 포인터 변수에 저장할 수 없도록 관리 하는 것이 소유권이라고 봐도 무방할 것 같다.
Earlier, we said that when a variable goes out of scope, Rust automatically calls the drop function and cleans up the heap memory for that variable. But Figure 4-2 shows both data pointers pointing to the same location. This is a problem: when s2 and s1 go out of scope, they will both try to free the same memory. This is known as a double free error and is one of the memory safety bugs we mentioned previously. Freeing memory twice can lead to memory corruption, which can potentially lead to security vulnerabilities. To ensure memory safety, after the line let s2 = s1;, Rust considers s1 as no longer valid. Therefore, Rust doesn’t need to free anything when s1 goes out of scope. Check out what happens when you try to use s1 after s2 is created; it won’t work: This code does not compile! let s1 = String::from("hello"); let s2 = s1; println!("{}, world!", s1); You’ll get an error like this because Rust prevents you from using the invalidated reference: $ cargo run Compiling ownership v0.1.0 (file:///projects/ownership) error[E0382]: borrow of moved value: `s1` --> src/main.rs:5:28 | 2 | let s1 = String::from("hello"); | -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait 3 | let s2 = s1; | -- value moved here 4 | 5 | println!("{}, world!", s1); | ^^ value borrowed here after move | = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider cloning the value if the performance cost is acceptable | 3 | let s2 = s1.clone(); | ++++++++ For more information about this error, try `rustc --explain E0382`. error: could not compile `ownership` due to previous error If you’ve heard the terms shallow copy and deep copy while working with other languages, the concept of copying the pointer, length, and capacity without copying the data probably sounds like making a shallow copy. But because Rust also invalidates the first variable, instead of being called a shallow copy, it’s known as a move. In this example, we would say that s1 was moved into s2. So, what actually happens is shown in Figure 4-4. |
[링크 : https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html]
+
단일 소유자면 어떻게 공유를 해? 했는데 검색해보니 다행히(!)
멀티 쓰레드 환경에서의 다중 소유권 내용이 존재한다.
다만 Rc는 thread safe하지 않으니 arc를 쓰란다.
Multiple Ownership with Multiple Threads In Chapter 15, we gave a value multiple owners by using the smart pointer Rc<T> to create a reference counted value. Let’s do the same here and see what happens. We’ll wrap the Mutex<T> in Rc<T> in Listing 16-14 and clone the Rc<T> before moving ownership to the thread. Filename: src/main.rs This code does not compile! use std::rc::Rc; use std::sync::Mutex; use std::thread; fn main() { let counter = Rc::new(Mutex::new(0)); let mut handles = vec![]; for _ in 0..10 { let counter = Rc::clone(&counter); let handle = thread::spawn(move || { let mut num = counter.lock().unwrap(); *num += 1; }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } println!("Result: {}", *counter.lock().unwrap()); } Listing 16-14: Attempting to use Rc<T> to allow multiple threads to own the Mutex<T> Once again, we compile and get... different errors! The compiler is teaching us a lot. $ cargo run Compiling shared-state v0.1.0 (file:///projects/shared-state) error[E0277]: `Rc<Mutex<i32>>` cannot be sent between threads safely --> src/main.rs:11:36 | 11 | let handle = thread::spawn(move || { | ------------- ^------ | | | | ______________________|_____________within this `[closure@src/main.rs:11:36: 11:43]` | | | | | required by a bound introduced by this call 12 | | let mut num = counter.lock().unwrap(); 13 | | 14 | | *num += 1; 15 | | }); | |_________^ `Rc<Mutex<i32>>` cannot be sent between threads safely | = help: within `[closure@src/main.rs:11:36: 11:43]`, the trait `Send` is not implemented for `Rc<Mutex<i32>>` note: required because it's used within this closure --> src/main.rs:11:36 | 11 | let handle = thread::spawn(move || { | ^^^^^^^ note: required by a bound in `spawn` --> /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/thread/mod.rs:704:8 | = note: required by this bound in `spawn` For more information about this error, try `rustc --explain E0277`. error: could not compile `shared-state` due to previous error Wow, that error message is very wordy! Here’s the important part to focus on: `Rc<Mutex<i32>>` cannot be sent between threads safely. The compiler is also telling us the reason why: the trait `Send` is not implemented for `Rc<Mutex<i32>>` . We’ll talk about Send in the next section: it’s one of the traits that ensures the types we use with threads are meant for use in concurrent situations. Unfortunately, Rc<T> is not safe to share across threads. When Rc<T> manages the reference count, it adds to the count for each call to clone and subtracts from the count when each clone is dropped. But it doesn’t use any concurrency primitives to make sure that changes to the count can’t be interrupted by another thread. This could lead to wrong counts—subtle bugs that could in turn lead to memory leaks or a value being dropped before we’re done with it. What we need is a type exactly like Rc<T> but one that makes changes to the reference count in a thread-safe way. Atomic Reference Counting with Arc<T> Fortunately, Arc<T> is a type like Rc<T> that is safe to use in concurrent situations. The a stands for atomic, meaning it’s an atomically reference counted type. Atomics are an additional kind of concurrency primitive that we won’t cover in detail here: see the standard library documentation for std::sync::atomic for more details. At this point, you just need to know that atomics work like primitive types but are safe to share across threads. You might then wonder why all primitive types aren’t atomic and why standard library types aren’t implemented to use Arc<T> by default. The reason is that thread safety comes with a performance penalty that you only want to pay when you really need to. If you’re just performing operations on values within a single thread, your code can run faster if it doesn’t have to enforce the guarantees atomics provide. Let’s return to our example: Arc<T> and Rc<T> have the same API, so we fix our program by changing the use line, the call to new, and the call to clone. The code in Listing 16-15 will finally compile and run: Filename: src/main.rs use std::sync::{Arc, Mutex}; use std::thread; fn main() { let counter = Arc::new(Mutex::new(0)); let mut handles = vec![]; for _ in 0..10 { let counter = Arc::clone(&counter); let handle = thread::spawn(move || { let mut num = counter.lock().unwrap(); *num += 1; }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } println!("Result: {}", *counter.lock().unwrap()); } Listing 16-15: Using an Arc<T> to wrap the Mutex<T> to be able to share ownership across multiple threads This code will print the following: Result: 10 We did it! We counted from 0 to 10, which may not seem very impressive, but it did teach us a lot about Mutex<T> and thread safety. You could also use this program’s structure to do more complicated operations than just incrementing a counter. Using this strategy, you can divide a calculation into independent parts, split those parts across threads, and then use a Mutex<T> to have each thread update the final result with its part. Note that if you are doing simple numerical operations, there are types simpler than Mutex<T> types provided by the std::sync::atomic module of the standard library. These types provide safe, concurrent, atomic access to primitive types. We chose to use Mutex<T> with a primitive type for this example so we could concentrate on how Mutex<T> works. |
[링크 : https://doc.rust-lang.org/book/ch16-03-shared-state.html]
스마트 포인터 하니 왜 cpp가 떠오르냐..(안봤음!)
아무튼 말 장난같은데
"소유권과 빌리는 컨셉에서 레퍼런스와 스마트 포인터 사이에는 추가적인 차이점이 있다." 라는 표현이 존재한다.
소유자가 1개가 원칙이나 스마트 포인터를 통해 소유자가 1 이상일 수 도 있다로 확장이 되려나?
Smart Pointers A pointer is a general concept for a variable that contains an address in memory. This address refers to, or “points at,” some other data. The most common kind of pointer in Rust is a reference, which you learned about in Chapter 4. References are indicated by the & symbol and borrow the value they point to. They don’t have any special capabilities other than referring to data, and have no overhead. Smart pointers, on the other hand, are data structures that act like a pointer but also have additional metadata and capabilities. The concept of smart pointers isn’t unique to Rust: smart pointers originated in C++ and exist in other languages as well. Rust has a variety of smart pointers defined in the standard library that provide functionality beyond that provided by references. To explore the general concept, we’ll look at a couple of different examples of smart pointers, including a reference counting smart pointer type. This pointer enables you to allow data to have multiple owners by keeping track of the number of owners and, when no owners remain, cleaning up the data. Rust, with its concept of ownership and borrowing, has an additional difference between references and smart pointers: while references only borrow data, in many cases, smart pointers own the data they point to. Though we didn’t call them as such at the time, we’ve already encountered a few smart pointers in this book, including String and Vec<T> in Chapter 8. Both these types count as smart pointers because they own some memory and allow you to manipulate it. They also have metadata and extra capabilities or guarantees. String, for example, stores its capacity as metadata and has the extra ability to ensure its data will always be valid UTF-8. |
[링크 : https://doc.rust-lang.org/book/ch15-00-smart-pointers.html]
'Programming > rust' 카테고리의 다른 글
rust mut (0) | 2023.05.25 |
---|---|
rust visibility and privacy (0) | 2023.05.25 |
rust was (0) | 2023.05.20 |
c에서 rust 호출하기 (0) | 2023.05.11 |
rust 실행파일 (0) | 2023.05.11 |
아래 명령은 openfoam221 쉘안에서 하니 되긴한데
openfoam2212:~/src/OpenFOAMTeaching/JozsefNagy/ minimonk$ fluentMeshToFoam elbow_tri.msh /*---------------------------------------------------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: 2212 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ Build : _f8e05934-20230403 OPENFOAM=2212 patch=230110 version=2212 Arch : "LSB;label=32;scalar=64" Exec : fluentMeshToFoam elbow_tri.msh Date : May 24 2023 Time : 16:38:06 Host : mini2760p PID : 23712 I/O : uncollated Case : /home/minimonk/src/OpenFOAMTeaching/JozsefNagy nProcs : 1 trapFpe: Floating point exception trapping enabled (FOAM_SIGFPE). fileModificationChecking : Monitoring run-time modified files using timeStampMaster (fileModificationSkew 5, maxFileModificationPolls 20) allowSystemOperations : Allowing user-supplied system call operations // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Create time --> FOAM FATAL ERROR: (openfoam-2212 patch=230110) cannot find file "/home/minimonk/src/OpenFOAMTeaching/JozsefNagy/system/controlDict" From virtual Foam::autoPtr<Foam::ISstream> Foam::fileOperations::uncollatedFileOperation::readStream(Foam::regIOobject&, const Foam::fileName&, const Foam::word&, bool) const in file global/fileOperations/uncollatedFileOperation/uncollatedFileOperation.C at line 561. FOAM exiting openfoam2212:~/src/OpenFOAMTeaching/JozsefNagy/ minimonk$ |
[링크 : https://youtu.be/KznljrgWSvo?t=1129]
[링크 : https://www.youtube.com/watch?v=KznljrgWSvo]
[링크 : https://openfoamwiki.net/index.php/Fluent3DMeshToFoam]
[링크 : https://github.com/jnmlujnmlu/OpenFOAMTeaching/tree/master/JozsefNagy]
$ openfoam openfoam = /usr/lib/openfoam/openfoam2212 * Using: OpenFOAM-v2212 (2212) - visit www.openfoam.com * Build: _f8e05934-20230403 (patch=230110) * Arch: label=32;scalar=64 * Platform: linux64GccDPInt32Opt (mpi=sys-openmpi) OpenFOAM shell session - use 'exit' to quit openfoam2212:~/src/tutorials/incompressible/icoFoam/elbow_tri/ minimonk$ fluentMeshToFoam elbow_tri.msh /*---------------------------------------------------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: 2212 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ Build : _f8e05934-20230403 OPENFOAM=2212 patch=230110 version=2212 Arch : "LSB;label=32;scalar=64" Exec : fluentMeshToFoam elbow_tri.msh Date : May 24 2023 Time : 17:15:20 Host : mini2760p PID : 24479 I/O : uncollated Case : /home/minimonk/src/tutorials/incompressible/icoFoam/elbow_tri nProcs : 1 trapFpe: Floating point exception trapping enabled (FOAM_SIGFPE). fileModificationChecking : Monitoring run-time modified files using timeStampMaster (fileModificationSkew 5, maxFileModificationPolls 20) allowSystemOperations : Allowing user-supplied system call operations // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Create time Reading header: "TGrid 2D 2.4.1" Reading header: "PreBFC V4.3" Dimension of grid: 2 Embedded blocks in comment or unknown: ( Embedded blocks in comment or unknown:( Found end of section in unknown:) Embedded blocks in comment or unknown:( Found end of section in unknown:) Found end of section in unknown:) Embedded blocks in comment or unknown: ( Embedded blocks in comment or unknown:( Found end of section in unknown:) Embedded blocks in comment or unknown: ( Found end of section in unknown:) Found end of section in unknown:) Embedded blocks in comment or unknown: ( Embedded blocks in comment or unknown:( Found end of section in unknown:) Found end of section in unknown:) Number of points: 537 number of faces: 1454 Number of cells: 918 Reading points Reading points Reading uniform faces Reading uniform faces Reading uniform faces Reading uniform faces Reading uniform faces Reading uniform faces Tgrid syntax problem: 9 1 396 1 cellGroupZoneID:9 cellGroupStartIndex:1 cellGroupEndIndex:918 cellGroupType:1 Read zone1:3 name:internal-3 patchTypeID:interior Reading zone data Read zone1:4 name:wall-4 patchTypeID:wall Reading zone data Read zone1:5 name:velocity-inlet-5 patchTypeID:velocity-inlet Reading zone data Read zone1:6 name:velocity-inlet-6 patchTypeID:velocity-inlet Reading zone data Read zone1:7 name:pressure-outlet-7 patchTypeID:pressure-outlet Reading zone data Read zone1:8 name:wall-8 patchTypeID:wall Reading zone data Read zone1:9 name:fluid-9 patchTypeID:fluid Reading zone data FINISHED LEXING dimension of grid: 2 Grid is 2-D. Extruding in z-direction by: 1.87548 Creating shapes for 2-D cells Building patch-less mesh...--> FOAM Warning : From Foam::polyMesh::polyMesh(const Foam::IOobject&, Foam::pointField&&, const cellShapeList&, const faceListList&, const wordList&, const wordList&, const Foam::word&, const Foam::word&, const wordList&, bool) in file meshes/polyMesh/polyMeshFromShapeMesh.C at line 645 Found 1990 undefined faces in mesh; adding to default patch defaultFaces done. Building boundary and internal patches. Creating patch 0 for zone: 3 start: 155 end: 1454 type: interior name: internal-3 Creating patch 1 for zone: 4 start: 55 end: 154 type: wall name: wall-4 Creating patch 2 for zone: 5 start: 47 end: 54 type: velocity-inlet name: velocity-inlet-5 Creating patch 3 for zone: 6 start: 43 end: 46 type: velocity-inlet name: velocity-inlet-6 Creating patch 4 for zone: 7 start: 35 end: 42 type: pressure-outlet name: pressure-outlet-7 Creating patch 5 for zone: 8 start: 1 end: 34 type: wall name: wall-8 Creating patch for front and back planes Patch internal-3 is internal to the mesh and is not being added to the boundary. Adding new patch wall-4 of type wall as patch 0 Adding new patch velocity-inlet-5 of type patch as patch 1 Adding new patch velocity-inlet-6 of type patch as patch 2 Adding new patch pressure-outlet-7 of type patch as patch 3 Adding new patch wall-8 of type wall as patch 4 Adding new patch frontAndBackPlanes of type empty as patch 5 Writing mesh... to "constant/polyMesh" done. End openfoam2212:~/src/tutorials/incompressible/icoFoam/elbow_tri/ minimonk$ tree . ├── 0 │ ├── U │ └── p ├── 0.orig │ ├── U │ └── p ├── Allclean ├── Allrun ├── constant │ ├── polyMesh │ │ ├── boundary │ │ ├── cellZones │ │ ├── faceZones │ │ ├── faces │ │ ├── neighbour │ │ ├── owner │ │ ├── pointZones │ │ └── points │ ├── transportProperties │ └── transportProperties.bak ├── elbow_quad.msh ├── elbow_tri.msh └── system ├── controlDict ├── foamDataToFluentDict ├── fvSchemes └── fvSolution 5 directories, 22 files openfoam2212:~/src/tutorials/incompressible/icoFoam/elbow_tri/ minimonk$ ico ico icoReactingMultiphaseInterFoam icoUncoupledKinematicParcelFoam iconv icoFoam icoUncoupledKinematicParcelDyMFoam icontopbm iconvconfig openfoam2212:~/src/tutorials/incompressible/icoFoam/elbow_tri/ minimonk$ icoFoam /*---------------------------------------------------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: 2212 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ Build : _f8e05934-20230403 OPENFOAM=2212 patch=230110 version=2212 Arch : "LSB;label=32;scalar=64" Exec : icoFoam Date : May 24 2023 Time : 17:19:48 Host : mini2760p PID : 24543 I/O : uncollated Case : /home/minimonk/src/tutorials/incompressible/icoFoam/elbow_tri nProcs : 1 trapFpe: Floating point exception trapping enabled (FOAM_SIGFPE). fileModificationChecking : Monitoring run-time modified files using timeStampMaster (fileModificationSkew 5, maxFileModificationPolls 20) allowSystemOperations : Allowing user-supplied system call operations // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Create time Create mesh for time = 0 PISO: Operating solver in PISO mode Reading transportProperties Reading field p Reading field U Reading/calculating face flux field phi Starting time loop Time = 0.05 Courant Number mean: 0.000415941 max: 0.173205 smoothSolver: Solving for Ux, Initial residual = 1, Final residual = 2.59879e-07, No Iterations 1 smoothSolver: Solving for Uy, Initial residual = 1, Final residual = 2.7558e-06, No Iterations 1 DICPCG: Solving for p, Initial residual = 1, Final residual = 0.036127, No Iterations 62 DICPCG: Solving for p, Initial residual = 0.0964781, Final residual = 0.00388218, No Iterations 3 DICPCG: Solving for p, Initial residual = 0.00947597, Final residual = 0.000467612, No Iterations 44 time step continuity errors : sum local = 7.42259e-05, global = 1.62183e-06, cumulative = 1.62183e-06 DICPCG: Solving for p, Initial residual = 0.00302872, Final residual = 0.000137611, No Iterations 9 DICPCG: Solving for p, Initial residual = 0.00040051, Final residual = 1.89259e-05, No Iterations 11 DICPCG: Solving for p, Initial residual = 7.55534e-05, Final residual = 7.72999e-07, No Iterations 55 time step continuity errors : sum local = 1.18435e-07, global = 2.9852e-09, cumulative = 1.62482e-06 ExecutionTime = 0.01 s ClockTime = 0 s Time = 0.1 Courant Number mean: 0.0788444 max: 0.397028 smoothSolver: Solving for Ux, Initial residual = 0.41777, Final residual = 1.43339e-06, No Iterations 2 smoothSolver: Solving for Uy, Initial residual = 0.415998, Final residual = 7.16337e-06, No Iterations 2 DICPCG: Solving for p, Initial residual = 0.0174141, Final residual = 0.000701295, No Iterations 60 DICPCG: Solving for p, Initial residual = 0.503317, Final residual = 0.0203323, No Iterations 3 DICPCG: Solving for p, Initial residual = 0.0837591, Final residual = 0.00367981, No Iterations 45 time step continuity errors : sum local = 6.59525e-05, global = -1.04379e-06, cumulative = 5.81027e-07 DICPCG: Solving for p, Initial residual = 0.104572, Final residual = 0.00332569, No Iterations 58 DICPCG: Solving for p, Initial residual = 0.257662, Final residual = 0.0119158, No Iterations 6 DICPCG: Solving for p, Initial residual = 0.0349453, Final residual = 6.69377e-07, No Iterations 73 time step continuity errors : sum local = 1.96408e-09, global = -3.1581e-11, cumulative = 5.80996e-07 ExecutionTime = 0.02 s ClockTime = 0 s ... Time = 74.95 Courant Number mean: 0.0810354 max: 0.50158 smoothSolver: Solving for Ux, Initial residual = 1.22107e-05, Final residual = 3.41265e-08, No Iterations 1 smoothSolver: Solving for Uy, Initial residual = 9.0529e-06, Final residual = 9.0529e-06, No Iterations 0 DICPCG: Solving for p, Initial residual = 0.000279752, Final residual = 1.15931e-05, No Iterations 5 DICPCG: Solving for p, Initial residual = 4.33362e-05, Final residual = 1.84484e-06, No Iterations 20 DICPCG: Solving for p, Initial residual = 1.21591e-05, Final residual = 9.52858e-07, No Iterations 6 time step continuity errors : sum local = 2.40141e-10, global = 4.53557e-11, cumulative = 5.99696e-07 DICPCG: Solving for p, Initial residual = 9.88006e-05, Final residual = 4.91478e-06, No Iterations 4 DICPCG: Solving for p, Initial residual = 1.34255e-05, Final residual = 9.18873e-07, No Iterations 18 DICPCG: Solving for p, Initial residual = 5.38886e-06, Final residual = 9.52181e-07, No Iterations 1 time step continuity errors : sum local = 2.39966e-10, global = -3.02947e-12, cumulative = 5.99693e-07 ExecutionTime = 6.25 s ClockTime = 7 s Time = 75 Courant Number mean: 0.0810354 max: 0.501578 smoothSolver: Solving for Ux, Initial residual = 1.29443e-05, Final residual = 3.26777e-08, No Iterations 1 smoothSolver: Solving for Uy, Initial residual = 8.86138e-06, Final residual = 8.86138e-06, No Iterations 0 DICPCG: Solving for p, Initial residual = 0.000425003, Final residual = 1.9758e-05, No Iterations 3 DICPCG: Solving for p, Initial residual = 3.72637e-05, Final residual = 1.5002e-06, No Iterations 47 DICPCG: Solving for p, Initial residual = 1.25032e-05, Final residual = 9.53705e-07, No Iterations 4 time step continuity errors : sum local = 2.40409e-10, global = -2.83052e-12, cumulative = 5.9969e-07 DICPCG: Solving for p, Initial residual = 8.65794e-05, Final residual = 4.13674e-06, No Iterations 8 DICPCG: Solving for p, Initial residual = 1.40349e-05, Final residual = 8.71206e-07, No Iterations 15 DICPCG: Solving for p, Initial residual = 4.26225e-06, Final residual = 7.88447e-07, No Iterations 1 time step continuity errors : sum local = 1.98748e-10, global = -4.50203e-11, cumulative = 5.99645e-07 ExecutionTime = 6.26 s ClockTime = 7 s End openfoam2212:~/src/tutorials/incompressible/icoFoam/elbow_tri/ minimonk$ |
여기는 연산하는 거고
이제 보는건 paraview를 쓰면 된다.
1. 좌측 상단의 폴더 눌러서 파일 열기
2. elbow_tri/system 디렉토리에서 파일을 모든 유형으로 선택하고 controlDict를 연다.
3. OpenFoam 유형으로 연다.
4. apply를 누른다.
(처음 열어 보면 그냥 wireframe만 나오는데, icoFoam 까지 하고 나서 다시 열면 색상이 보인다)
5. 상단에 U로 바꾸어 주고 재생 버튼을 누르면 75초간 시뮬레이션 한 결과가 재생된다.
오.. 신기해라(영혼 없음)
'프로그램 사용 > openFOAM' 카테고리의 다른 글
mpirun illegal instruction (0) | 2023.09.01 |
---|---|
openFOAM + freecad + salome (0) | 2023.06.07 |
openfoam on ubuntu (0) | 2023.05.24 |
openFOAM tutorial (4) | 2023.05.24 |
openfoam7 on ubuntu 18.04 (0) | 2020.08.09 |