質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1071閲覧

TypeError:NoneTypeを解決したい

ab-3

総合スコア5

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/09/09 04:46

編集2021/09/09 07:48

プログラミング未経験の者です。以下リンク、科学技術計算講座3-熱伝導方程式シミュレーションリンク内容を参考にして、厚さ1mmのSi材料にレーザー光を一定時間照射したときの試料の温度分布を求めたいと思っています。
試料は一次元(深さ)方向のみ考えており位置i、時間nとそれぞれを離散化しています。(照射)時間に比例、深さ方向に対しては指数関数的に減少するレーザー光の吸収熱Qを設定し、一次元非定常熱伝導方程式をもとにFTCS差分式の右辺第1項に足しました。
計算を行ったところ、#①の吸収熱Q のみが計算され#②の部分でTypeError:unsupported operand type(s) for +:'NoneType'and'float'が表示されました。#②の計算式の中で#①で設定した吸収熱QがNoneTypeとなっており、ほかのtemp[i]などに足せないため、returnで関数に実態をもたせる必要があると調べてみて考えたのですが、プログラミング経験がないこともあり、具体的な解決策が分かっていません。
基礎的なところかと思いますが、ご回答いただけるとありがたいです。

コードの情報(lx:厚さ、dx :空間分割の幅、nx:空間分割点数 、tend:計算期間、dt:時間刻み、nt :時間のステップ数)

import

1import matplotlib.animation as animation 2import numpy as np 3 4# input parameter(材料をSiに変更、厚さ1㎜、a:吸収係数、微小間隔 dx:10㎛、計算期間1μs、時間間隔1nsに変更、表面温度を固定しないためtemp_bcを消去) 5den = 2330.0 6cp = 678.0 7cond = 83.7 8temp_init = 0.0 9lx = 0.001 10nx = 101 11tend = 0.000001 12dt = 0.000000001 13tout =0.000001 14a=0.064 15alpha = cond / (den * cp) 16dx = lx / (nx - 1) 17nt = int(tend / dt) 18nout = int(tout / dt) 19 20 21# ①レーザー光照射による吸収熱Qの設定 ※50ns間照射して表面温度2000℃を想定 22for i in range(1, nx-1): 23 x=dx*i 24 25for n in range(1, nt+1): 26 t=dt*n 27 Q=print(40000000000*t*pow(2.718281828,-a*x)) 28 29 30 31# レーザー光照射時間の指定 32t_intv= 0.00000005 33 34 35#initial condition 36temp = np.full(nx, temp_init) 37time = 0.0 38 39temp_new = np.zeros(nx) 40 41# Boundary condition(表面温度temp[0]固定の# Dirichlet @ x=0条件をNeumann条件に変更) 42temp[0] = temp[1] 43temp[nx-1] = temp[nx-2] # Neumann @ x=Lx 44 45# graph data array 46ims = [] 47fig = plt.figure() 48ax = fig.add_subplot(1, 1, 1) 49 50gx = np.zeros(nx) 51for i in range(nx): 52 gx[i] = i * dx 53 54# time loop 55for n in range(1, nt+1): 56 57 #② FTCS差分式(右辺第一項に吸収熱を設定/0~50nsの間だけ照射、それ以降はQ=0)) 58 for i in range(1, nx-1): 59 if time < t_intv : 60 temp_new[i] = Q+temp[i] + dt * alpha * (temp[i+1] - 2.0 * temp[i] + temp[i-1]) / (dx * dx) 61 else : 62 temp_new[i] = temp[i] + dt * alpha * (temp[i+1] - 2.0 * temp[i] + temp[i-1]) / (dx * dx) 63 64 # update 65 for i in range(1, nx-1): 66 temp[i] = temp_new[i] 67 68 # Boundary condition(表面温度temp[0]固定の# Dirichlet @ x=0条件をNeumann条件に変更) 69 temp[0] = temp[1] 70 temp[nx-1] = temp[nx-2] # Neumann @ x=Lx 71 72 time += dt 73 74 if n % nout == 0: 75 print('n: {0:7d}, time: {1:8.1f}, temp: {2:10.6f}'.format(n, time, temp[nx-1])) 76 im_line = ax.plot(gx, temp, 'b') 77 im_time = ax.text(0, 110, 'Time = {0:8.1f} [s]'.format(time)) 78 ims.append(im_line + [im_time]) 79 80# graph plot 81ax.set_xlabel('x [m]') 82ax.set_ylabel('Temperature [C]') 83ax.grid() 84anm = animation.ArtistAnimation(fig, ims, interval=50) 85anm.save('animation.gif', writer='pillow') 86plt.show() 87 88

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ppaul

2021/09/09 05:27

実行しようとすれば、いろいろとエラーが出ていますね。 少なくとも文法エラーはない状態にしてから再度質問してください。
ab-3

2021/09/09 05:57

ご指摘ありがとうございました。
guest

回答1

0

ベストアンサー

コード組むより先に、基礎を先にすべきです。

一応書いておきますが。

※ 私自身は数学が苦手なうえ、「...xを離散化し...」のような部分はよくわからないので、一応動くまでのものとします。(計算自体が間違っていたらどうにもならない)


一旦、質問にあるコードをPaiza IOで実行してみると、

そもそもエラーになります。

Traceback (most recent call last): File "Main.py", line 4, in <module> dx = lx / (nx - 1) NameError: name 'lx' is not defined [訳] トレースバック(最近呼ばれたもの): "Main.py"ファイルの 4行目で、NameErrorが発生! dx = lx / ... NameError: "lx"という名のものは存在しないっす

NameError……公式によると、例外のようです。

簡単に言えば、存在しない変数等を使っていることが原因の例外です。

そして、コードを読むと、

dx = lx / (...) というような4行目で初めて lx が出ています。

でもこのlxとは何でしょうか。

人間にはわかっていても、実際に処理するのは人間ではなく機械です。

機械は言われたことしかできません。

存在しないものを呼び出そうとしているのだから、エラーに。

仮に人間がやるとしても、質問者さんはこの状態で数学の問題として出されたとかと考えてみてください。

「ん? lx の値ってなんやねん!?」って突っ込みたくなりませんか?

nx は 101 とわかっていますが、lx はありません。
そうなると、

dx = lx / 100

となります。でもこれをdxを求めよと言われて、解けますか?

私には無理です。だってlxがわからないから。

それと、今回の、「math.40exp(-ax)*tが文字として100個表示されるだけでした」ですが、
当たり前です。

上記エラー(例外)を対処したとしても、当たり前です。

なぜか。

それはそのように命令しているからです。

プログラムを実行するのは機械です。
機械は言われた通りにしか動きません。

ではコードを見てみましょうか。

コードを読むコツは「一行レベルで、何をしているかを考えながら読む」です。

やってみましょう。

# 変数 nx は 101 nx = 101 # 変数 tend は 0.000001 tend = 0.000001 # 変数 dt は 0.000000001 dt = 0.000000001 # 変数 lx は 1 (← 勝手に付け加えた。読みかえてください) lx = 1 # 変数 dx はnx - 1 で lx を割ったもの dx = lx / (nx - 1) # nt は tend を dt で割った値だが、int型として丸め込む nt = int(tend / dt) # ... (同じように) a=0.064 # [1, nx-1) の範囲でループさせる for i in range(1, nx-1): # 変数 x は dx に i をかけたもの x=dx*i # [1, nt+1) の範囲でループさせる for n in range(1, nt+1): # 変数 t は dt に n をかけたもの t=dt*n # "math.40*exp..." という「文字列として」表示 print("math.40*exp(-a*x)*t")

これを疑似コードとして切り出してみましょう。

1. 変数 nx は 101 2. 変数 tend は 0.000001 ... 7. 変数 a は 0.064 8. [1, nx-1) の範囲でループ ( as i ) 8.1. 変数 x を用意し、dx に i をかけたものである 9. [1, nt+1) の範囲でループ ( as n ) 9.1. 変数 t を用意し、dt に n をかけたものである 9.2. 「文字列として」、"math.40*exp..." を表示する

この疑似コードを現実世界でシミュレーションしてみてください。
つまり、数学の問題を解くとかのような感覚で実際にやってみる。

そうすると、「あれぇ???? なんで俺、(9.1)で文字列として表示しているのかな?」と思いませんか?

"..." で囲むと文字列となります。

それに、(8.1)で求めた x は大丈夫でしょうか?

(計算できないのであえてしませんが)

投稿2021/09/09 07:40

BeatStar

総合スコア4962

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問