Cluster parallel

All python based solutions listed on are investivated.

Projects without a github link are filtered out. These are usually repos too old or not well maintained, without proper issue-solving mechanism.

Projects with too little github stars are filtered out.

The rest shows that "ray" and "celery" are the two most prominent candidate, followed by "dask" and "deap".


To begin with, IBM LSF is tried first since it's the recommended tool. However, the functions does not meet my requirements. LSF fundamentally lacks a programmable interface.


"ray" is deployed successfully on the campus hpc, but problems are encounted that cannot be found and solved. Trials are also made to deploy "ray" on newer systems. The results are as following.

  • zju-i1c311-ws0-u: successful
  • zju-i19b118-ws0-u: successful
  • zju-i19b118-ws1-u: successful
  • zju-i1b305-ws0-u: successful deployment, error when running, probably caused by wsl
  • zju-i1c410-ws0-c: successful deployment, error when running, probably caused by centos 7
  • zju-i19b118-mgt01 with 40 nodes: successful deployment, unstable running result, sometimes successful, sometimes error, unusuable.

n2n is used to avoid firewall port restriction.

Although the deplyment and running are successful on the first 3 nodes, ray shows problems on load balancing, which is yet to be solved.

However, the ray dashboard serves great.


It is possible to write one's own parallel framework. In fact, a tool 'bexec' have been made to allow parallel execution of commands (e.g. ray manangement commands) on hpc, using python multiprocessing and ssh.

To diy such a framework, there are problems to be solved and requirements to be met as following:

  • remote connection
    • paramiko for reusable ssh connection: too buggy, too slow, cannot make it work
    • alternatives with detail comparison is found at
    • parallel-ssh also has similar problems, solved by deploying ed25519 keys (also paramiko) turned out 8192 bit rsa is not well supported
  • resource balance
    • monitoring of remaining resource with accuracy and efficiency
  • fault tolerance
    • node problem
    • worker problem
    • process problem
  • avoid management node bottleneck
    • async and threading based task schedulling does not run on multiple cores

Despite the cluster can run, the performance is task scheduler bottlenecked. In both case of paramiko and parallel-ssh, I cannot make multiprocessing on these two work due to 'can not pickle'.

The framework, however, can still be used in future where task scheduler is not a bottleneck.

Better still, parallel-ssh proves to be a good parallel command tool, which is what it's designed to be. Scripts are written to manage ray and celery instances using parallel-ssh.


It works.

celery + rabbitmq + redis works.

All 5 workstations managed by me work smoothly, including 3 ubuntu 22.04, 1 ubuntu 20.04, and 1 centos 7.9. This gives 128+64+32+24+32=280 physical cores, or 560 threads.

Of all the 45 hpc nodes, all centos 7.4, 2 nodes (mgt01, mgt02, fat01) are management nodes, 3 nodes (ndoe28, node31, gpu08) are not physically not available, making a total of 39 nodes available to use. This gives 1904 physical cores, or 2072 threads.

One of the workstation is choosen to be the head node where the tasks are assigned, messages passed with rabbitmq, and results collected by redis. This gives a toatal of 280+1904-64=2120 physical cores, or 560+2072-128=2504 threads.

All the tasks are set with 19 nice value, i.e. lowest priority to keep a low profile and minimize influence on other users. Even though it is still competitive enough against other users' tasks. The head node would show delay on processing other nodes' celery heartbeats should it be filled with tasks too.

1904 cores cost ¥190.4 per hour, for a campus public facility this is very arrogant. However, an inspection into the billing system shows that it counts only the lsf record, thus all these calculation are done for free! This is clearly an exploit, but a rule is a rule and the price is set obviously improperly. In fact, members of the administration board have an unclear 'discount' on using the cluster, which could be the actual reasonable price. Now that the billing system is both arrogant and stupid, I see no point to make it smart while remaining arrogant.

The actual exploit lies that the cluster nodes allow direct ssh access other than through lsf.


Some notes on mouting smb on campus hpc.

export $(dbus-launch)
gio mount -u smb://[email protected]/path

should there be no folder under /run/user/{uid}/gvfs

/usr/lib/gvfs/gvfsd-fuse /run/user/{uid}/gvfs












DDPM equation derivation

This derivation is partly enlightened by 1.

As the DDPM paper describes, the forward process can be stated as following

q(\mathbf{x}_t|\mathbf{x}_{t-1}) := \mathcal{N}(\mathbf{x}_t, \sqrt{1-\beta_t}\mathbf{x}_{t-1}, \beta_tI)


\alpha_t := 1 - \beta_t
\tilde{\alpha_t} := \prod_{s=1}^t{a_s}

using reparametrization trick

\begin{aligned} q(\mathbf{x}_t|\mathbf{x}_{t-1}) & = \sqrt{1-\beta_t} \mathbf{x}_{t-1} + \sqrt{\beta_t} \boldsymbol{\epsilon} \\ & = \sqrt{\alpha_t} \mathbf{x}_{t-1} + \sqrt{1-\alpha_t} \boldsymbol{\epsilon} \\ &= \sqrt{\alpha_t}\mathbf{x}_{t-1} + \sqrt{(1 - \alpha_t) + \alpha_t (1-\alpha_{t-1})} \boldsymbol{\epsilon} \\ & = \sqrt{\alpha_t \alpha_{t-1}} \mathbf{x}_{t-2} + \sqrt{1-\alpha_t \alpha_{t-1}} \boldsymbol{\epsilon} \\ & = \sqrt{\alpha_t \alpha_{t-1} \alpha_{t-2}} \mathbf{x}_{t-3} + \sqrt{1-\alpha_t \alpha_{t-1} \alpha_{t-2}} \boldsymbol{\epsilon} \\ & = \dots \\ & = \sqrt{\alpha_t \alpha_{t-1} ... \alpha_1} \mathbf{x}_0 + \sqrt{1-\alpha_t \alpha_{t-1} ... \alpha_1 } \boldsymbol{\epsilon} \\ & = \sqrt{\prod_{s=1}^t{a_s}} \mathbf{x}_0 + \sqrt{1-\prod_{s=1}^t{a_s} } \boldsymbol{\epsilon} \\ & = \sqrt{\tilde{\alpha_t}} \mathbf{x}_0 + \sqrt{1-\tilde{\alpha_t} } \boldsymbol{\epsilon} \\ \end{aligned}

The forward process can be stated as following

p(x_{t-1} | x_t) := \mathcal{N}(x_{t-1}; \mu_\theta(x_t, t), \Sigma_\theta(x_t, t))

where we fix the variance \Sigma_\theta(x_t, t) to a certain schedule

using variational lower bound, the loss function

\begin{aligned} -\log{p_\theta(\mathbf{x}_0)} & \leq -\log{p_\theta(\mathbf{x}_0)} + D_{KL}(q(\mathbf{x}_{1:T} | \mathbf{x}_0) || p_\theta (\mathbf{x}_{1:T} | \mathbf{x}_0)) \\ & = -\log{p_\theta(\mathbf{x}_0)} + \log{{\frac{q(\mathbf{x}_{1:T} | \mathbf{x}_0)}{p_\theta (\mathbf{x}_{1:T} | \mathbf{x}_0)}}} \\ & = -\log{p_\theta(\mathbf{x}_0)} + \log{{\frac{q(\mathbf{x}_{1:T} | \mathbf{x}_0)}{\frac{p_\theta(\mathbf{x}_0 | \mathbf{x}_{1:T}) p_\theta(\mathbf{x}_{1:T})}{p_\theta(\mathbf{x}_0)}}}} \\ & = -\log{p_\theta(\mathbf{x}_0)} + \log{{\frac{q(\mathbf{x}_{1:T} | \mathbf{x}_0)}{\frac{p_\theta(\mathbf{x}_0, \mathbf{x}_{1:T})}{p_\theta(\mathbf{x}_0)}}}} \\ & = -\log{p_\theta(\mathbf{x}_0)} + \log{{\frac{q(\mathbf{x}_{1:T} | \mathbf{x}_0)}{\frac{p_\theta(\mathbf{x}_{0:T})}{p_\theta(\mathbf{x}_0)}}}} \\ & = -\log{p_\theta(\mathbf{x}_0)} + \log{{\frac{q(\mathbf{x}_{1:T} | \mathbf{x}_0)}{{p_\theta(\mathbf{x}_{0:T})}}}} + \log{{p_\theta(\mathbf{x}_0)}} \\ & = \log{{\frac{q(\mathbf{x}_{1:T} | \mathbf{x}_0)}{{p_\theta(\mathbf{x}_{0:T})}}}} \\ \end{aligned}

though simplified, can not be directly calculated yet.

\begin{aligned} -\log{p_\theta(\mathbf{x}_0)} & = \log{\frac{\prod_{t=1}^T{q(\mathbf{x}_t | \mathbf{x}_{t-1})}}{p(\mathbf{x}_T) \prod_{t=1}^T{p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t)}}} \\ & = \log{\frac{\prod_{t=1}^T{q(\mathbf{x}_t | \mathbf{x}_{t-1})}}{p(\mathbf{x}_T) \prod_{t=1}^T{p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t)}}} \\ & = -\log{p(\mathbf{x}_T)} + \log{\frac{\prod_{t=1}^T{q(\mathbf{x}_t | \mathbf{x}_{t-1})}}{\prod_{t=1}^T{p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t)}}} \\ & = -\log{p(\mathbf{x}_T)} + \sum_{t=1}^T{\log{\frac{q(\mathbf{x}_t | \mathbf{x}_{t-1})}{p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t)}}} \\ & = -\log{p(\mathbf{x}_T)} + \sum_{t=2}^T{\log{\frac{q(\mathbf{x}_t | \mathbf{x}_{t-1})}{p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t)}}} + \log{\frac{q(\mathbf{x}_1 | \mathbf{x}_0)}{p_\theta(\mathbf{x}_0 | \mathbf{x}_1)}} \\ & \leq -\log{p(\mathbf{x}_T)} + \sum_{t=2}^T{\log{\frac{q(\mathbf{x}_t | \mathbf{x}_{t-1}, \mathbf{x}_0)}{p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t)}}} + \log{\frac{q(\mathbf{x}_1 | \mathbf{x}_0)}{p_\theta(\mathbf{x}_0 | \mathbf{x}_1)}} \\ & = -\log{p(\mathbf{x}_T)} + \sum_{t=2}^T{\log{\frac{q(\mathbf{x}_{t-1} | \mathbf{x}_t, \mathbf{x}_0) q(\mathbf{x}_t | \mathbf{x}_0)}{p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t) q(\mathbf{x}_{t-1} | \mathbf{x}_0)}}} + \log{\frac{q(\mathbf{x}_1 | \mathbf{x}_0)}{p_\theta(\mathbf{x}_0 | \mathbf{x}_1)}} \\ & = -\log{p(\mathbf{x}_T)} + \sum_{t=2}^T{\log{\frac{q(\mathbf{x}_{t-1} | \mathbf{x}_t, \mathbf{x}_0)}{p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t)}}} + \sum_{t=2}^T{\log{\frac{q(\mathbf{x}_t | \mathbf{x}_0)}{q(\mathbf{x}_{t-1} | \mathbf{x}_0)}}} + \log{\frac{q(\mathbf{x}_1 | \mathbf{x}_0)}{p_\theta(\mathbf{x}_0 | \mathbf{x}_1)}} \\ & = -\log{p(\mathbf{x}_T)} + \sum_{t=2}^T{\log{\frac{q(\mathbf{x}_{t-1} | \mathbf{x}_t, \mathbf{x}_0)}{p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t)}}} + \log{\frac{q(\mathbf{x}_t | \mathbf{x}_0)}{q(\mathbf{x}_1 | \mathbf{x}_0)}} + \log{\frac{q(\mathbf{x}_1 | \mathbf{x}_0)}{p_\theta(\mathbf{x}_0 | \mathbf{x}_1)}} \\ & = -\log{p(\mathbf{x}_T)} + \sum_{t=2}^T{\log{\frac{q(\mathbf{x}_{t-1} | \mathbf{x}_t, \mathbf{x}_0)}{p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t)}}} + \log{\frac{q(\mathbf{x}_t | \mathbf{x}_0)}{p_\theta(\mathbf{x}_0 | \mathbf{x}_1)}} \\ & = \log{\frac{q(\mathbf{x}_t | \mathbf{x}_0)}{p(\mathbf{x}_T)}} + \sum_{t=2}^T{\log{\frac{q(\mathbf{x}_{t-1} | \mathbf{x}_t, \mathbf{x}_0)}{p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t)}}} - \log{p_\theta(\mathbf{x}_0 | \mathbf{x}_1)} \\ & = \underbrace{D_{KL}(q(\mathbf{x}_t | \mathbf{x}_0) || p(\mathbf{x}_T))}_{L_T} + \sum_{t=2}^T{\underbrace{D_{KL}(q(\mathbf{x}_{t-1} | \mathbf{x}_t, \mathbf{x}_0) || p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t))}_{L_{t-1}}} \underbrace{- \log{p_\theta(\mathbf{x}_0 | \mathbf{x}_1)}}_{L_0} \\ \end{aligned}

where the Kullback–Leibler divergence

D_{KL}(p || q) = \int_x{p(x) \log{{\frac{p(x)}{q(x)}}dx}} \geq 0

measures how similar two distributions are

now LT = D{KL}(q(x_t | x_0) || p(x_T)) describes the similarity between a forward process and a random noise, thus this term can be ignored

within L_{t-1}

q(\mathbf{x}_{t-1} | \mathbf{x}_t, \mathbf{x}_0) \sim \mathcal{N}(\mathbf{x}_{t-1}; \tilde{\boldsymbol{\mu}_t}(\mathbf{x}_t, \mathbf{x}_0), \tilde{\beta_t} I)


\begin{aligned} & q(\mathbf{x}_{t-1} \vert \mathbf{x}_t, \mathbf{x}_0) \\ = & q(\mathbf{x}_t \vert \mathbf{x}_{t-1}, \mathbf{x}_0) \frac{ q(\mathbf{x}_{t-1} \vert \mathbf{x}_0) }{ q(\mathbf{x}_t \vert \mathbf{x}_0) } \\ \propto & \exp \Big(-\frac{1}{2} \big(\frac{(\mathbf{x}_t - \sqrt{\alpha_t} \mathbf{x}_{t-1})^2}{\beta_t} + \frac{(\mathbf{x}_{t-1} - \sqrt{\tilde{\alpha}_{t-1}} \mathbf{x}_0)^2}{1-\tilde{\alpha}_{t-1}} - \frac{(\mathbf{x}_t - \sqrt{\tilde{\alpha}_t} \mathbf{x}_0)^2}{1-\tilde{\alpha}_t} \big) \Big) \\ = & \exp \Big(-\frac{1}{2} \big(\frac{\mathbf{x}_t^2 - 2\sqrt{\alpha_t} \mathbf{x}_t {\mathbf{x}_{t-1}} {+ \alpha_t} {\mathbf{x}_{t-1}^2} }{\beta_t} + \frac{ {\mathbf{x}_{t-1}^2} {- 2 \sqrt{\tilde{\alpha}_{t-1}} \mathbf{x}_0} {\mathbf{x}_{t-1}} {+ \tilde{\alpha}_{t-1} \mathbf{x}_0^2} }{1-\tilde{\alpha}_{t-1}} - \frac{(\mathbf{x}_t - \sqrt{\tilde{\alpha}_t} \mathbf{x}_0)^2}{1-\tilde{\alpha}_t} \big) \Big) \\ = & \exp\Big( -\frac{1}{2} \big( {(\frac{\alpha_t}{\beta_t} + \frac{1}{1 - \tilde{\alpha}_{t-1}})} \mathbf{x}_{t-1}^2 - {(\frac{2\sqrt{\alpha_t}}{\beta_t} \mathbf{x}_t + \frac{2\sqrt{\tilde{\alpha}_{t-1}}}{1 - \tilde{\alpha}_{t-1}} \mathbf{x}_0)} \mathbf{x}_{t-1} + C(\mathbf{x}_t, \mathbf{x}_0) \big) \Big) \end{aligned}


\begin{aligned} \tilde{\beta}_t &= 1/(\frac{\alpha_t}{\beta_t} + \frac{1}{1 - \tilde{\alpha}_{t-1}}) = 1/(\frac{\alpha_t - \tilde{\alpha}_t + \beta_t}{\beta_t(1 - \tilde{\alpha}_{t-1})}) = {\frac{1 - \tilde{\alpha}_{t-1}}{1 - \tilde{\alpha}_t} \cdot \beta_t} \\ \tilde{\boldsymbol{\mu}}_t (\mathbf{x}_t, \mathbf{x}_0) &= (\frac{\sqrt{\alpha_t}}{\beta_t} \mathbf{x}_t + \frac{\sqrt{\tilde{\alpha}_{t-1} }}{1 - \tilde{\alpha}_{t-1}} \mathbf{x}_0)/(\frac{\alpha_t}{\beta_t} + \frac{1}{1 - \tilde{\alpha}_{t-1}}) \\ &= (\frac{\sqrt{\alpha_t}}{\beta_t} \mathbf{x}_t + \frac{\sqrt{\tilde{\alpha}_{t-1} }}{1 - \tilde{\alpha}_{t-1}} \mathbf{x}_0) {\frac{1 - \tilde{\alpha}_{t-1}}{1 - \tilde{\alpha}_t} \cdot \beta_t} \\ &= \frac{\sqrt{\alpha_t}(1 - \tilde{\alpha}_{t-1})}{1 - \tilde{\alpha}_t} \mathbf{x}_t + \frac{\sqrt{\tilde{\alpha}_{t-1}}\beta_t}{1 - \tilde{\alpha}_t} \mathbf{x}_0\\ &= \frac{\sqrt{\alpha_t}(1 - \tilde{\alpha}_{t-1})}{1 - \tilde{\alpha}_t} \mathbf{x}_t + \frac{\sqrt{\tilde{\alpha}_{t-1}}\beta_t}{1 - \tilde{\alpha}_t} \frac{1}{\sqrt{\tilde{\alpha}_t}}(\mathbf{x}_t - \sqrt{1 - \tilde{\alpha}_t}\boldsymbol{\epsilon}) \\ &= \frac{1}{\sqrt{\alpha_t}} ( \mathbf{x}_t - \frac{1 - \alpha_t}{\sqrt{1 - \tilde{\alpha}_t}} \boldsymbol{\epsilon} ) \end{aligned}

also within L_{t-1}

p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t) = \mathcal{N}(\mathbf{x}_{t-1}; \boldsymbol{\mu}_\theta(\mathbf{x}_t, t), \boldsymbol{\Sigma}_\theta(\mathbf{x}_t, t))

now define the loss as MSE of \tilde{\boldsymbol{\mu}_t}(\mathbf{x}_t, \mathbf{x}0) and \boldsymbol{\mu}\theta(\mathbf{x}_t, t)

L_t = \frac{1}{2 \sigma_t^2}||\tilde{\boldsymbol{\mu}_t}(\mathbf{x}_t, \mathbf{x}_0) - \boldsymbol{\mu}_\theta(\mathbf{x}_t, t)||^2

now that we need to train \boldsymbol{\mu}_\theta to predict \tilde{\boldsymbol{\mu}_t} = \frac{1}{\sqrt{\alpha_t}} ( \mathbf{x}_t - \frac{1 - \alpha_t}{\sqrt{1 - \tilde{\alpha}_t}} \boldsymbol{\epsilon} ), we can reparameterize the Gaussian noise term instead to make it predict \boldsymbol{\epsilon}_t from the input \mathbf{x}_t at time step t

\boldsymbol{\mu}_\theta(\mathbf{x}_t, t) = \frac{1}{\sqrt{\alpha_t}} ( \mathbf{x}_t - \frac{1 - \alpha_t}{\sqrt{1 - \bar{\alpha}_t}} \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) )

now we can rewrite

\begin{aligned} L_t & = \frac{1}{2 \sigma_t^2}||\tilde{\boldsymbol{\mu}_t}(\mathbf{x}_t, \mathbf{x}_0) - \boldsymbol{\mu}_\theta(\mathbf{x}_t, t)||^2 \\ & = \frac{1}{2 \sigma_t^2}||\tilde{\boldsymbol{\mu}_t}(\frac{1}{\sqrt{\alpha_t}} ( \mathbf{x}_t - \frac{1 - \alpha_t}{\sqrt{1 - \tilde{\alpha}_t}} \boldsymbol{\epsilon} )) - \frac{1}{\sqrt{\alpha_t}} ( \mathbf{x}_t - \frac{1 - \alpha_t}{\sqrt{1 - \bar{\alpha}_t}} \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) )||^2 \\ & = \frac{\beta_t^2}{2\sigma_t^2 (1-\tilde{a_t})} ||\boldsymbol{\epsilon} - \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)||^2 \end{aligned}


\begin{aligned} p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t) &= \mathcal{N}(\mathbf{x}_{t-1}; \boldsymbol{\mu}_\theta(\mathbf{x}_t, t), \boldsymbol{\Sigma}_\theta(\mathbf{x}_t, t)) \\ &= \mathcal{N}(\mathbf{x}_{t-1}; \frac{1}{\sqrt{\alpha_t}} ( \mathbf{x}_t - \frac{1 - \alpha_t}{\sqrt{1 - \bar{\alpha}_t}} \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) ), \beta_t) \\ \end{aligned}

leading to

\mathbf{x}_{t-1} = \frac{1}{\sqrt{\alpha_t}} ( \mathbf{x}_t - \frac{1 - \alpha_t}{\sqrt{1 - \bar{\alpha}_t}} \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) ) + \sqrt{\beta_t} \boldsymbol{\epsilon}

L0 = - \log{p\theta(\mathbf{x}_0 | \mathbf{x}_1)} can be minimized if we have a close enough prediction of \mathbf{x}_0 with \mathbf{x}_1.


  1. L. Weng, “What are diffusion models?”, Jul 2021. [Online]. Available: 

让子弹飞 三刷

汤师爷 武智冲 胡万



郭沫若 钟南山 Humphery




毛泽东 孙中山 Caesar




林彪 Labienus Antony

















袁世凯 蒋介石




see also

《让子弹飞》的政治隐喻--毛泽东式的革命理想 - 中國論壇 - udn城市

《让子弹飞》《一步之遥》与《邪不压正》:革命,后革命与“前”革命 _ 赵皓阳 - RESSRC

Dingtalk video download

  1. search url containing m3u8
    1. might start with
    2. must in the foramt of playUrl.*m3u8
  2. url-decode the request
  3. get playUrl
  4. download the m3u8 file
  5. N_m3u8DL-CLI_v3.0.2.exe
    1. BASEURL = something like, can be found by searching 1.ts
    2. cli params like "C:\Users\Mark\Downloads\97d17bb3-c046-4335-9711-26bda5162b9a_normal.m3u8" --saveName "97d17bb3-c046-4335-9711-26bda5162b9a_normal" --baseUrl ""

Asperger syndrome

I am now self-diagnoised as Asperger, according to following:


Baron-Cohen, Simon & Cassidy, Sarah & Auyeung, Bonnie & Allison, Carrie & Achoukhi, Maryam & Robertson, Sarah & Pohl, Alexa & Lai, Meng-Chuan. (2014). Attenuation of Typical Sex Differences in 800 Adults with Autism vs. 3,900 Controls. PloS one. 9. e102251. 10.1371/journal.pone.0102251.

Asperger syndrome

From Tamiko Ridley's comment on her daughter Reagan Ridley, Inside Job.

Am I? No.

The enlightment is not to bring perfectionism/maticulousness into social interactions.

Keep it everywhere else.

Inside Job: TV series review

Futurama but at current times. Various conspiracy theory instead of sci-fi fantacy. Reagan as Leela the leader, Brett as Fry the fool, with their colleagues as the office members.

Blowing one's mindset just like Rick and Morty but more usually in terms of morality sarcasm. What they do have in common, the despise of hypocritic morality, the confidence of running the world (literally), the respect for reason, science, and knowledge, the sense of liberty and freedom of souls.



I chose React as the framework of the frontend. Despite I have been developing using React, this is the first React project of mine that starts from scratch. MUI seems pretty handy.

So it went online now.

There are still a lot of bugs to fix and features to add, but I'll take a breath before carrying on. Atm, finding costomers with requirement prevails my service to provide.

structured data in database

Consider the following data structure to implement in a database:

class ComponentBase:
    name: str
    def serialize(self):
        assert False

class ComponentA(ComponentBase):
    def serialize(self):

class ComponentB(ComponentBase):
    def serialize(self):


class ComponentList(ComponentBase):
    children: list[ComponentWrapper | ComponentList | ComponentSet | ComponentA | ComponentB ...]
    def serialize(self):

class ComponentSet(ComponentBase):
    children: set[ComponentWrapper | ComponentList | ComponentSet | ComponentA | ComponentB ...]
    def serialize(self):

class ComponentWrapper(ComponentBase):
    target: ComponentList | ComponentSet | ComponentA | ComponentB
    def serialize(self):

The purpose of a database implementation is to query like 'which componentWrapper recursively includes a given componentA?', 'get all the related componentB of a gievn componentWrapper', and such.

And the trouble arises not only because there is a list to maintain (performance concern), but also, there are unions of types (how? all in one table?), and loops in definition (safety concern, unknown depth problem).

The current approach uses json field to store the data above, which solves all the problem at the expense of additional backend workload (it basically reads everything into memory) which I intend to avoid.

Well it all depends on actual requirements. Reading the database recursively is actually acceptable compared to loading the entire table into memory. Saving list as a json value is acceptable when the lists only have length of like 10.

Best solution would be the recursive approach with cache field to avoid deep loop when querying. However, this would make configuration harder as pure json appoach is much more human readable than nested sql table entries. Moreover, it means the updating certain value of database will now have to go through the backend to ensure the cache is valid. Even then, the cache updating is more complicated than normal one-way cache. It has to be in both direction, allowing it to propagate through any cache that it relys on, and that relys on it. Consider all of these troubles the price of performance. Such huge modification would mean some fundamental change of the program... Maybe when I have time.

If I do it, this would be the 4th major version of this program, by major I mean none of these versions is back compatible. The cause of such iteration is that the need of requirement and need of performance is quite divided, and I am kinda stuck in between. It's difficult to vision all the requirement in advance, and optimization usually limits future functions.

Pantheon: TV series review



Steve, founder and CEO of the best company of his time, tried to upload human mind to Matrix and almost succeeded. To ensure the job is kept on even after his eraly death of some incurable cancer, he opted to make a clone of himself. The clone would then be nurtured in the Truman Show based on Steve's own biography to ensure his genius.

  • Steve Jobs, the reality layer.
  • Trumen Show, the connection layer and sideline.
  • Matrix, the sci-fi layer, the metaverse.

It's good TV series in terms of story, great anime production in terms of visulization, but still, it lacks true sci-fi innovation of concept, and not quite consistant in character personality development and logic, in other words it feels awkward to watch from time to time.

plot holes

With the ability to manipulte the entire internet with root access to every device connected, the 'gods' seem quite unimaginative.

The antagonist turns out to have mental problems, which lowers the credibility of the entire set.

The latest development includes some very interesting settings about immortality. I guess the story hasn't quite prepared to introduce the ture enternity. The flaw, that the uploaded mind will decay over usage shows significant similarity to those of original life, which is both reasonable and disappointing. Having such a limit on its core sci-fi setting creates a sense that it's just a common story with some sci-fi tech, restricting further development.

easter eggs

The antagonist, an Indian, shared the tech with 'nations of top cyber', which turns out to be US, Russia, UK, Isreal, Iran, and China. Cannot say if he is trying to protect India by not letting them know such technology. Also, France is the only absent P5. P.S. 20221005 I just learned that the writer, Ken Liu, is a Chinese... all make sense now.


It takes the life of a protagonist to make an antagonist. Classic Joffery move. But too many plotholes,too may stereotypes.

Why no backup when everything is digitalized? Why physical annihilation when code injection is much more easy and cost effective?

As to the classic 'Chinese people are kind and reasonble it's CCP causing problems'... It would definitely be interesting to find out how a Chinese degenerated into a white left. Sure, it might not be the problem of Ken but the ideology gets across nontheless.




20220925 损伤自诊













膝关节内侧副韧带(medial collateral ligament,MCL)由 MCL 浅层(superficial MCL,sMCL)、深层(deep MCL,dMCL)以及后斜韧带(posterior oblique ligament,POL)三部分组成,是维持膝关节外翻及旋转稳定性的重要结构。sMCL 是 MCL 中最表浅的韧带,是维持膝关节外翻稳定性的主要结构,也是维持膝关节旋转稳定性的次要结构[1-2]。POL 是维持膝关节内旋稳定性的主要结构,也是维持膝关节外翻和外旋稳定性的次要结构[3-5]。生物力学研究发现,膝关节屈曲 25° 时,sMCL 提供 78% 的抗外翻和外旋应力;而膝关节屈曲 0°~30° 时,POL 对维持内旋稳定性发挥关键作用[1, 6]。因此,同时有效地修复 sMCL 和 POL,对恢复膝关节稳定性和生物力学性能起着重要作用。

MCL 损伤是临床常见的运动损伤类型,根据 Hughsyon 标准[7]分为 3 级。单纯 Ⅰ、Ⅱ级损伤无需手术治疗[8];合并前交叉韧带(anterior cruciate ligament,ACL)损伤的 Ⅲ 级损伤需要手术干预,以避免膝关节外翻松弛及旋转不稳,进而继发膝关节骨关节炎及外翻畸形,影响患者运动水平及生活质量[9-10]。


考虑到直行走路尚可,因此交叉韧带损伤概率低(即使损伤也需要伤2周后再手术),认为是Ⅰ或Ⅱ 级损伤,因此维持现状保守治疗,尽可能卧床休息,保持直腿或在15度弯曲内,降低sMCL受力(疼痛为准),观察至两周。



20220930 损伤自诊










20221003 转诊海宁市人民医院



20221004 MRI





20221010 康复






20221014 自诊










20221017 转诊浙大二院




  • 海宁市人民医院:2个月不能走路不能动(未提及髁间嵴)
  • 海宁市人民医院:(未看片)立即开始康复
  • 无锡市中医院:(诱导结论)髁间嵴有骨折可能需手术
  • 浙大二院:前叉韧带及髁间嵴没事(立即开始康复)


20221019 康复




  1. Xie W, Zhu W. Biomechanical comparison of single-bundle and anatomical double-bundle reconstructions for grade Ⅲ medial collateral ligament injury]. Zhongguo Xiu Fu Chong Jian Wai Ke Za Zhi. 2020 Jun 15;34(6):720-725. Chinese. doi: 10.7507/1002-1892.201911057. PMID: 32538562; PMCID: PMC8171538. 

  2. 后交叉韧带损伤机制及治疗方法 

  3. 这36种骨折,影像医生值夜班时千万不要漏诊! - 知乎 

  4. 儿童胫骨髁间棘骨折 - 好大夫在线 

  5. Wadugodapitiya, Surangika et al. ‘Assessment of Knee Collateral Ligament Stiffness by Strain Ultrasound Elastography’. 1 Jan. 2022 : 337 – 349. 

Electric Long Board

This is going to be a long sequal.

20220831 1st try

While I was at Berkeley, a girl Lin taught me how to ride a skateboard. I remember I shot the photo of the tall grass right next to the training course that night. That 1.5 hour of practice was all I had with skateboard before I decided to buy an electric one. Technically I do have childhood experience on toy boards, which was driven by twisting, could be a reason why I learned fast.

It paid well. Within the first half hour I was able to cruise at 20 km/h and do normal turns with radius of 3 meters at lower speed. I tried to reach top speed but the board began to shake heavily before I can reach that fast.

20220905 2nd try, reach top speed

4 days of raining stopped my training.

I learned from reddit and Youtube that the 'shaking' I experienced at high speed was called wobbling and it is due to my feet position. By putting my front foot right on the front wheel, I can now accelerate to top speed (but still too cautious to look at the speed meter, it was about 38km/h according to the seller) without any problem.

It is still dangerous to go on road at this stage because I still cannot make sharp turns and fast stops.

On my search for how to make sharp turns, I found there is actually a style called carving in some Youtube videos 12. I will practise that next time.

20220906 carving

I can now pass the corner at 20 km/h, within lane. The actual top speed is 35 km/h at half battery.

Carving is interesting, but I can not drift yet. It could be due to wrong posture, or simply because the board has too good a grip. No matter what, carving is definitely a good way to learn to control the board.

I tried to look for some groups on telegram, facebook, or QQ. Some of these groups are really active, and gave me some really good advice.

For example I was adviced to get a regular board to practise sharp turns and stop. I vaguely remember I could do a sharp turn on a regular board though.

20220912 first accident

I've been using the eskateboard for commuting in the past few days. Today I falled from a skateboard and crashed on land for the first time in my life. It was due to fast break (from >30km/h) before the turn.

This accident proves that the decision to protect myself using only engineering gloves was necessary and almost sufficient under such circumstances. There are further risk of grazing my elbow or bumping my head should I get unlucky though. It turns out 20km/h might be the safe boundry for daily commute.

20220916 ride on the other side

I borrowed a regular board from another classmate. It is slightly shorter, has wheels of half the size, and a much softer bridge. It turned out accelerating on a regular board is much harder.

I taught one of my friends to ride a eskaeboard too.

I also start practising riding on the other side, i.e. with my right foot in front, contrary to normal.

20220917 Yuquan campus

I went to another campus with my eskateboard today. It turned out I have mastered the riding on busy and unfamiliar streets.

I continued to practise on the other side. It seems most of the balance control memory are not transferrable and I have to learn them from like 0. Obviously, balance control is something beyond conciousness. I expect twice or third learning period since I will not use this side for daily commuting.

20220920 Accident


Go, GORM, and gRPC

v2ray-core is written in Go.

So I tried GORM as yet another alternative to SQLAlchemy and Django. GORM can manage the database by migration just as Django does, and this part works fluently.

As to the config side, it feels uncomfortably hard to implement a model-based configurator in Go. Despite I can get all the struct directly from v2ray-core, they come with very strict type definitions. Implementing another model feels unnecessary, and is troublesome too - no type union, no constructor, no default value for functions. Indeed, Go is not an object-oriented language.

For scenarios where performance is not a problem, Python will do so I am going to save the trouble of reimplementing the whole project yet again in Go.

However, I do still need Go for gRPC for some features of v2ray to work. I can either use a Python package for that, or I can use the GORM model defined earlier to write gRPC directly in Go. The first approach is considered better in the long run because I can save the trouble of aligning the Python and Go ORM model.


ordered list in a database

Previous development reveals that relation-based databases cannot properly handle arrays that need insert() method.

A hack is to use a string-based index that allows gaps between indexes so that insertion can be realized without reordering the rest of the entries. 1

This is feasible on the SQL level but the availability under ORM tools still needs investigation.

ORM: SQLAlchamy vs Django

On the ORM side, I also tried Django as an alternative to SQLAlchamy.

Some major difference includes:

  • Django builds the database according to the model, while SQLAlchamy requires manual mapping. This may be a desired feature for fast development but comes at a cost of less extensibility as an ORM
  • Django model object links to each other by a query manager while SQLAlchamy object links to each other directly. The Django way will cause a problem in type hint that would require further hacks like django_hint and manual type decalration everytime a query is made. I consider this as a feature missing bug of Django
  • Django comes with a lot of other features since it's developed as more of a website backend than a simple ORM



I spent 2 days redeveloping a v2ray config generator to fulfill my increasing demand for proxy server configuration.

Currently, I have more than 20 different simple configurations (i.e. one-level proxy) for more than 10 servers. Despite a lot of them being just servers of different domains to balance the load across CDN, managing all of them with complex proxy chains is a headache. A typical proxy chain configuration can reach 500+ lines of JSON, which is quite some work to write even one. Moreover, several of my friends are using the services too, which makes the configuration even harder.

I wrote a super long python script to work with a sqlite3 database one year ago trying to automate the process. It worked well until the demand for proxy chains arises. Due to the lack of knowledge and foresight, I use raw SQL to extract information into python dictionaries. This works at a simple level, but the model information is lost during the process. The work became exponentially more difficult as the requirement became complex.

With all the knowledge acquired last year, I re-implement the program with python and sqlite3, again. But this time I use sqlalchamy and jsonpickle so that I can model the configuration instead of using just dictionaries. It turned out that such a method facilitates my development to a great extent.

I also rebuild the database model. The complete database structure is shown below.

service.chain and virtual_server.chain actually depends on address_group, server, reverse_server, and virtual_server. However, these information are stored in JSON so can not be seen from the database structure.

At this stage, I only implement the config class of my requirement so a lot of functions of v2ray are neglected, thus not ready to be published as a public library.

Asymmetric routing and campus firewall

the problem

Despite Zhejiang University having a clear university-wide policy on domain registration, a Haining campus Information Technology Services (ITS) officer Z told me the campus has its own policy that refuses to follow due to 'security concern'. In other words, the Haining campus refuses to assist with University domain reverse proxy, such that any user who wants to have an Internet-accessible server will have to have its server located elsewhere. In my situation, it means an extra ¥2200/year cost to rent a VPS from ZJU main campus.

The actual scenario is, the Haining campus has internal connections with other ZJU campuses. In my situation, with the service still deployed on a local server, with a forwarded proxy from main campus VPS, any security breach would still happen locally, meaning the 'security concern' is nothing but a poorly made excuse.

Well, since the administrative board is not responsible for users in a typical Chinese-style organization, I will have to fix this issue by myself.

Interestingly, the reverse proxy can be actually configured from the main campus alone, and it should work without problem. So I circumvent the Haining campus ITS and registered a domain reverse proxy directly with the main campus.

The result is, strange. I noticed the server is indeed Internet accessible when applying for an HTTPS certificate, but local tests show that it can not be accessed from within China. In other words, it is accessible only from abroad.

the cause

I spent an entire afternoon trying to figure out why, and with hints from the main campus IT support and traceroute output, I finally discovered that the problem lies in asymmetric routing.

More detailly, all outgoing traffic from the Haining campus is redirected according to its destination. Traffic going abroad is going through the main campus exit, while others directly through the local campus exit. Now since the incoming traffic is all from the main campus entrance, this path is symmetrically routed, and the other one is not. The asymmetric routing will be blocked by the firewall due to DDOS attack prevention.

the fix

Now that I know the cause of the problem, the dillema arises that I still need Haining campus ITS's assistance to fix the issue. I need to make sure even those administrative roles like Z saw my request, they would not understand my true purpose. Considering Z's earlier response, she was either in an administrative position, or is really rookie in the network engineering field, both case I bet she would not want, or be designated to look into some issues too technical to understand.

A ticket is then sent to the Haining campus ITS to request all outgoing traffic of a specific ip to go through the main campus network gateway 'due to asymmetric routing' for 'research purpose, and to avoid incidental firewall block', together with some specified gateway ip I got from traceroute log. It turned out Z was not designated to the ticket.

Now that this is an existed routing, they accepted the reqest 'after requesting superior instruction'. Problem solved.

the bureaucracy

The is a typical bureaucracy 'there are policies and measures to counter' incident.

It turned out, I got lucky because incompetent officer like Z is indeed, incompetent. But this also means tragedy for all those who can not conceive a counter, and thus have to live with trash policies made by those incompetent officers.

On the other hand, trash policy actually works because not enough people know how to counter it, so the incompetent officer can remain in position.

To knowledge.

Reveal all HSAP without ‘modified’ tag

This is a log rather than a tutorial. It does one very specific thing, to reveal all HSAPs without getting 'modified' tag. Though I think the method of injecting/calling script without modified tag is worth sharing.


I have my HQ deployed at Unclaimed Sector behind Xenon Secot 524. So When I learned there could be a Unclaimed Sector beta but it's not in my game due to some game start randomness I try to bring it back without losing my game progress or getting a 'modified' tag.



  • write a script z.cheat.mkmark.revealall.hsap.xml to reveal all HSAPs based on cycrow's revealall cheat script, and add a fake signiture
  • extract plugin.turbo.hotkey.xml from corresponding pck file, backup the pck, then replace the pck by a modified xml where z.cheat.mkmark.revealall.hsap are replaced by plugin.turbo.activate
  • follow the 'Unmodifier' instruction to launch a game
  • activate turbo boost in game

the plain script of z.cheat.mkmark.revealall.hsap.xml

$main.universe = get global variable: name='main.universe'
skip if $main.universe -> exists
  $main.universe = get sector from universe index: x=0, y=0
skip if $main.universe -> exists
  $main.universe = [PLAYERSHIP] -> get sector

$x = get max sectors in x direction
while $x
  $y = get max sectors in y direction
  dec $x =
  while $y
    dec $y =

    $sector = get sector from universe index: x=$x, y=$y
    skip if $sector -> exists

    $flags = [Find.ExcludeTerranGates] | [Find.ExcludeGates] | [Find.Hyperspeed]
    $hsap = find gate: flags=$flags, refobj=$sector, max dist=null, refpos=null
    if $hsap -> exists
      if $hsap ->is hyperspeed access point
        if not $hsap ->is hsap discoverable
          if is valid route between sectors $main.universe and $sector
            $hsap -> set hsap discoverable [TRUE]

return null


Raspberry Pi libcamera low-latency http streaming

  • model: Raspberry Pi 4B
  • system: Ubuntu 22.04 aarch64

Through resources of Pi http streamings are widely available over the Internet, few address the libcamera library which is the only option under aarch64, and few address the low-latency part of the streaming.

I managed to achieve the above with the following:

This process has a very low latency due to the rendering workload being undertaken by the client, while Pi just hardware encoding the video into h264 and serving the binary directly.


Text is not SVG - cannot display


  • compile libcamera following the guide
  • compile libcamera-apps following the guide
  • install websockify following the guide
  • launch the following, or optionally create systemd services of these commands
    libcamera-vid -t 0 --width 1920 --height 1080 --inline --listen -o tcp://
  • create static nginx html server with /rpicam/index.html as following

    <meta name="color-scheme" content="dark">
    <script type="text/javascript" src="[email protected]/dist/jmuxer.min.js"></script>
            margin: 0;
    <div id="container" style="width: 100%; margin: 0 auto;">
        <div class="vsc-controller"></div>
        <video width="100%" autoplay muted id="player"></video>
        function parse(data) {
            var input = new Uint8Array(data),
            video = input;
            return {
                video: video,
        window.onload = function () {
            var socketURL = document.location.href.replace('http', 'ws')+'ws/';
            var jmuxer = new JMuxer({
                node: 'player',
                mode: 'video',
                flushingTime: 0,
                fps: 30,
                debug: false
            var ws = new WebSocket(socketURL);
            ws.binaryType = 'arraybuffer';
            ws.addEventListener('message', function (event) {
                var data = parse(;
  • configure nginx server to serve /rpicam/ to static file directory, and /rpicam/ws/ to Typical configuration of the later is as following.
    location /rpicam/ws/ {
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

known issues and solutions

  • current configuration can support only one client at a time
    • a dedicated backend to stream tcp/websocket data to multiple clients would be necessary
  • libcamera-vid will exit each time websocket is closed
    • auto restart is possible using systemd
    • if one have a dedicated backend this can be managed
  • no audio is served. jmuxer supports audio, to combine audio one will have to either
    • write a dedicated backend to repackage the binary data by adding audio and duration information
    • or serve audio through a seperate websocket, but could lead to audio/video being not synchronized

For now I am happy with the result, but a dedicated backend would be optimal/necessary to solve these issues.

Campus network exploitation

original plan with exploit

The campus has strange regulations to restrict outbound speed but not LAN speed. The goal was to utilize every accessible computer with wired LAN access to speed up my campus outbound connections. By using load balancer over a large number of computers the outbound bandwidth is combined for multithread downloading. n2n is used to connect devices with admin access for easy management, direct v2ray is deployed to devices without admin access but with fixed ip and port access, and v2ray of reverse proxy is to deploy to devices without fixed ip and admin access.

new exploits

While I was examing the campus HPC I noticed something strange: the outbound speed is not limited (in terms of LAN speed) on the HPC. This is reasonable consider that many people are using the cluster. Furthermore, the HPC is shared with commercial users from outside the campus, and further inspection confirms that the HPC outbound is a direct link to local China Telecom network instead of China Education and Research Network. This is a major advantage as the former one is much more reliable and efficient.

First of all, I only have a user account on the HPC, meaning opening ports on firewall is out of the quesiton, let alone creating tun devices. A common practise under such situation would be creating a reverse proxy to another server.

However, a port scan shows local 90 and 8080 port is open but unused. Port 90 is unavailable to common users, but 8080 is totally accessible. This is unexpected as well as hilarious. Nginx and v2ray is then deployed with ws+tls+vmess to provide maximum security. Crontab is configured to ensure availablity across reboot.

sudo nmap -n -Pn -sS -p0-65535 [ip]


Due to the unlimited outbound speed of HPC the connection bottle neck is now the campus LAN. Ping to various servers drops significantly due to the advantage of China Telecom over CERNET. Secure connections are established. While all operations are under campus regulation, some part of the process should be seen as exploits.

potential counter measures

To counter the exploits campus net admin would have to:

  • properly configure firewall of public workstations
  • block all ports of LAN devices to avoid NAT traversal, which is totally unreasonable, or
  • restrict the LAN speed to outbound speed, which is equivelantly unreasonable

Before that the campus network outbound speed limit is merely a trash policy, an inconvenience, rather than a restriction. Considering the inconvenience inflicted, and the total legal and reasonable process, I hardly find any motivation to report such exploits.

Backup and synchronization summary

Disk failure costs. As a general rule, all valuable data should be kept in copy, preferably on different devices, in real time, and with 2-way sychronization support.

In the early days I had been using robocopy with batch script, rsync with shell script, even adb-sync with batch/shell scripts. Configurations were complex, the backup system was vulnerable to various compatibility problems (typically system locale problems and path naming restrictions). The backup was also not in real time, nor does these methods support 2-way sychronization due to the absense of a database.

Commercial solution costs, while a lot of open-source solutions do not work in a real-time fashion.

Syncthing is a great tool to solve the problems above. It even comes with bundled NAT traversal capability. A typical backup network shows as below,

Text is not SVG - cannot display

where arrow shows backup direction, solid line represents user files, and dash line represents system files.

Some personal files are sychronized across devices as needed, while backup operations typically have the following ignore cases.

Linux user

.stignore at $HOME


Linux root

.stignore at /


Windows user

.stignore at %userprofile%

\Documents\Tencent Files\*\TIM\Registry2.0.db
\Documents\Tencent Files\*\TIM\Registry2.0.db-journal

Proxy summary

I built a proxy network allowing me to access various resources across the Internet. As shown in the figure below, servers on different locations are deployed and connected by either direct proxy (solid line) or reverse proxy (dash line). connection mapping are labelled in the format of '(x to y) * z', indicating z groups of x clients each connecting to y servers.

1 to m
1 to m
n2n edge
s to n
s to n
server * s
n2n supernode
server * s...
(n/k to 1) * k
(n/k to 1) * k
CDN server * n
CDN server * n...
VPS server * k
VPS server * k...
reverse proxy
1 to n
1 to n
1 to k
1 to k
China campus
China campus...
Internet VPS
Internet VPS...
Internet campus
Internet campus...
reverse proxy
server * (m-s)
n2n edge
server * (m-s)...
(m-s) to n
(m-s) to n
Text is not SVG - cannot display

by tools

  • v2fly/v2ray-core: secure proxy, balancer, router
    • Qv2ray/Qv2ray: v2ray gui for pc
    • SagerNet/SagerNet: v2ray gui for android
  • ntop/n2n: virtual LAN adaptor
  • alexkirsz/dispatch-proxy: adaptor combiner
  • nginx/nginx: server side http proxy, http reverse proxy, http port reuse
  • haad/proxychains: proxy chains, socks,http->app, for pc
  • proxifier: proxy chains, socks,http->app, for windows
  • ambrop72/badvpn/tun2socks: socks->adaptor
  • torproject/tor,tpo/applications/tor-browser: anonymous http
  • FelisCatus/SwitchyOmega: socks,http->browser

by application senario

bypass GFW with server port access

  • v2fly/v2ray-core+nginx/nginx: vmess+ws+tls->socks5, balancer, multiple domain cdn servers for acceleration and camouflage

bypass campus Internet outbound speed limit (campus has no LAN speed limit)

has LAN servers with server port access

  • v2fly/v2ray-core+nginx/nginx: vmess+ws->socks5, balancer, multiple in-campus servers for acceleration, speed *= number of servers

without servers

  • alexkirsz/dispatch-proxy: LAN + WLAN + USB LAN + USB hotspot: speed *= 4

reverse proxy without server port access

  • v2fly/v2ray-core: reverse proxy
  • microsoft/vscode: temporary port forwarding

LAN traversal with server root access

  • ntop/n2n


  • campus LAN should be seen as public with even more strict censorship but less decryption ability, never use unencrypted proxy in campus LAN
  • watch out for DNS leak, use firewall rules to block port 53 if necessary
  • if necessary use firewall rules to block all connections except localhost proxy

rss news

why rss

rss is the best solution to aggregate news with the advantages of being

  • free, no ads, no tracking, no targeting
  • highly customizable
  • across platform
  • decentralized

In short, by using rss we can choose sources rather than being targeted by algorithms with ads and propaganda.





The guideline is to choose from most unbiased media, i.e. AP and Reuters. Their positional (western) bias is then offset using TASS and 人民网 for voices from Russia and China.

This strategy covers:

  • Top 4 of the 5 UN security council members, with the exception of France
  • 3 of the 5 larget news agencies, with the exception of UPI which is yet another US news agency, and Agence France-Presse which does not provide mature english content.


  • 六子吃了两碗粉 - 让子弹飞
  • 伊拉克有生化武器 - US Congress
  • 新疆维吾尔族强迫劳动 - US Gov
  • 武汉病毒研究所制造新冠病毒 - US Gov
  • 中国要求俄罗斯奥运会结束再开战 - NY Times


体系:利益方 - 枪手 - 媒体 - 缺乏判断力的群众






  • 无视 成本最低,有刻意回避的负面效果
  • 简单否认 成本极低,效果一般。
  • 要求控方拿出切实有效的证据 抬升控方成本,转移焦点
  • 允许控方调查 成本不可控且毫无意义
  • 有公共认可的第三方,允许第三方调查 成本偏高,抬升控方成本,效果一般但通常能较为长期地解决问题
  • 反向污蔑/合理怀疑 成本偏高,降低自身道德标准,丧失公信力
  • 揭露控方诽谤的本质 成本取决于控方诽谤的水平,需要发掘控方犯下的错误,长期来看能降低控方公信力
  • 引诱控方犯下低级错误的诽谤 难度极高,钓鱼执法



Russia seeks military equipment from China after Ukraine invasion -reports March 14, 2022 9:09 PM GMT+0 第一步:提出指控 重点: 匿名美国官员 无法提供细节 白宫国家安全委员会拒绝评论 可以解读为: 真:俄罗斯军事无法负担乌克兰战争 假:无意义

Chinese embassy says has never heard of Russian requests for help March 14, 2022 9:20 PM GMT+0 第二步:等待否认 可以解读为: 真:前报道不实,事件毫无意义。 假:中国在撒谎,且对俄罗斯背信弃义


U.S. warns China not to help Russia as anti-war protest disrupts state TV 第三步:道德绑架

外交部发言人就美方签署所谓 “维吾尔强迫劳动预防法案”发表谈话

2021-12-24 08:46 当地时间12月23日,美方将所谓“维吾尔强迫劳动预防法案”签署成法。该案罔顾事实真相,恶意诋毁中国新疆人权状况,严重违反国际法和国际关系基本准则,粗暴干涉中国内政,中方对此表示强烈愤慨、坚决反对。 所谓新疆地区存在“强迫劳动”和“种族灭绝”,完全是反华势力炮制的恶毒谎言。新疆经济发展和社会安定举世公认,各族人民安居乐业有目共睹。美方反复借涉疆问题造谣生事,实质是打着人权的幌子搞政治操弄和经济霸凌,企图破坏新疆繁荣稳定、遏制中国发展。 美国自身劣迹斑斑,就人权问题指责抹黑中国是滑天下之大稽。美国是贩卖人口和强迫劳动的重灾区,近5年来每年被贩卖到美国从事强迫劳动的人口多达10万。美国历史上对印第安原住民犯下的反人类罪行早已构成事实上的“种族灭绝”。“强迫劳动”和“种族灭绝”这两顶帽子还是美国留着自己戴最合适。 涉疆问题根本不是人权问题,而是反暴恐和反分裂问题。中方正告美方,利用涉疆问题搞阴谋诡计,阻挡不了新疆各族人民追求美好生活的坚定步伐,阻挡不了中国不断发展壮大。美方行径完全违背市场规则和商业道德,只会破坏全球产业链供应链稳定,扰乱国际贸易秩序,损害美自身利益和国家信誉,纯属搬起石头砸自己的脚。 我要再次强调,涉疆事务纯属中国内政。中国政府和人民捍卫国家主权、安全和发展利益的决心坚定不移。我们奉劝美方立即纠正错误,停止利用涉疆问题散布谎言、干涉中国内政、遏制中国发展。中方将视形势发展作进一步反应。


2021/08/28   8月27日,美国国家情报总监办公室发布所谓“新冠病毒溯源调查报告”要点,认为目前看新冠病毒源自自然界和实验室泄漏的两种可能性都不能排除。报告诬蔑中方阻挠国际调查、拒绝共享信息并指责他国。白宫同日就新冠病毒溯源调查发布声明,妄称中方阻挠溯源工作的国际调查,缺乏透明度,企图纠集有关伙伴方对中方施压。中方对此坚决反对、强烈谴责。   首先,报告是美由情报部门主导杜撰的,毫无科学性和可信度可言。新冠病毒溯源是科学问题,应该也只能由科学家而不是情报专家研究。历史上,美情报部门搞出不少“杰作”,诸如把一小瓶洗衣粉当作伊拉克大规模杀伤性武器证据,自导自演“白头盔”组织摆拍所谓“叙利亚化学武器袭击”视频。现在美方又故技重施,放着中国—世卫组织联合研究报告不信,偏要取信情报部门炮制的报告,那怎么还可能是科学、可靠的溯源?   第二,美方声称中方不透明,这完全是为其推动政治化、污名化寻找借口。疫情发生以来,中方始终本着公开、透明、负责任原则,第一时间对外介绍、对外分享病毒基因序列、对外开展抗疫合作。2019年12月27日,武汉地方有关部门首次报告可疑病例,30日下发关于做好不明原因肺炎救治工作的紧急通知,31日中国向世卫组织通报有关情况,2020年1月3日中方开始定期向世卫组织和美国等有关国家主动通报疫情信息。在溯源问题上,中方也从一开始就表明了科学、专业、严肃和负责任的态度,率先同世卫组织开展全球溯源合作,去年以来两次邀请世卫专家来华开展溯源研究。世卫专家组来华开展溯源工作时,中方完全公开透明,满足了其全部参访要求,未作任何限制。专家们在武汉去了所有他们想去的地方,会见了所有他们想见的人,查看了所有他们想看的资料。世卫组织3月30日正式发布的中国—世卫组织联合研究报告,其形成遵循了世卫组织程序,采取了科学方法,体现了权威性和科学性。中方在病毒溯源问题上展现的开放、透明态度也得到国际专家充分肯定。   第三,美方情报部门出台报告恰恰说明了美方一意孤行在政治操弄的错误道路上越走越远。疫情暴发以来,美国成为感染和死亡人数最多的国家,已经让美国民众付出了沉重代价。美国政府通过情报机构搞所谓溯源报告,妄图对中国进行“有罪推定”,是为了推卸自身抗疫失败责任、向中国甩锅推责。美方这种做法只会对国际溯源和全球抗疫合作造成干扰和破坏,已经遭到国际社会普遍反对。世界上100多个国家和地区,300多个政党、社会组织和智库向世卫组织秘书处提交《联合声明》,坚决反对将溯源问题政治化。美方难道不应该听一听这些声音吗?   最后,美方对自身溯源讳莫如深,把溯源大门关得死死的。美方如果真的“透明负责”,就该公布并检测早期病例数据。美国新冠肺炎疫情发生的时间线不断前移。美国至少有五个州的新冠病毒感染情况早于美国首例确诊病例报告时间。近日也有美国媒体报道,美国首例新冠肺炎死亡病例出现的时间为2020年1月初,比官方此前认定的2月初要早数周。   武汉病毒研究所已两次接待世卫组织专家,新冠病毒源自武汉病毒研究所泄漏“极不可能”是中国—世卫组织联合研究报告得出的明确结论。美方如果非要坚持实验室泄漏的说法,难道不应该邀请世卫组织专家前往德特里克堡和北卡罗来纳大学调查吗?德堡长期从事冠状病毒研究、改造,2019年发生严重安全事故并被关停,随后美国国内暴发与新冠肺炎症状相似的疾病。北卡大学巴里克团队早就具备极其成熟的冠状病毒合成及改造能力,该校于2015年1月至2020年6月1日共向美国国立卫生研究院报告28起涉及基因工程微生物的安全事故,其中6起涉及包括SARS、MERS和新冠病毒等在内的冠状病毒。美方不调查公布自家实验室的情况,却光顾着往别人身上泼脏水。   中方对全球溯源问题的立场是一贯、明确的。溯源是科学问题,中方始终支持并将继续参加科学溯源。我们反对的是政治操弄,反对的是有罪推定,反对的是嫁祸于人。第二阶段溯源应该在第一阶段溯源的基础上全面延伸,在全球多国多地开展溯源工作,才能真正找到真相和答案。   美情报部门提供的报告没有给出美方想要的确切答案,再搞下去,也是竹篮打水一场空,因为它的调查本身就是子虚乌有、反科学的。














  1. 俄罗斯把乌克兰北东南三面合围以后不动了。既不合拢口袋,也不攻城。说明俄罗斯不着急。西乌部队肯定不会往口袋里钻,那无异于自杀。东乌政府军正面没有打赢的可能,长期来看除了撤退就是投降,没有别的选择。
  2. 俄罗斯没有切断乌西南即波兰罗马尼亚边境,甚至都没往西乌进军,尤其是北约武器现在在往西乌不断输送的情况下,说明俄对西乌没有任何兴趣。
  3. 表面上和乌克兰谈判但完全不停军事行动,说明俄罗斯没达到预期目标。
  4. 很多人说乌克兰会变成下一个阿富汗,我看未必。乌克兰地形缺乏打游击的条件,大平原重武器的对抗游击队根本活不了。乌克兰有抵抗意志但目前远没到阿富汗的血海深仇。



  1. 是否承认东乌各国独立
  2. 是否承诺永不入欧,永不入北约
  3. 是否承诺去军事化


Ukraine War



The biggest, if not only, winner of the event. The only one who wishes the event to happen, so that money can go back to US from EU (due to regional instability) to reduce the high inflation in US.

The only loss would be the confidence of US's allies accounting on its support.

If Russia does not invade Ukraine, NATO will be dancing at its doorstep which is super preferable to EU and US, but intolerable as to Russia.

If Russia invades Ukraine, EU and Russia will be against each other by sharing a military border, so that US (and UK) will have much less to worry about on these two opponents.


Has no advantage but military strength, has no means of diplomacy but threatening, has no choice but war. Pity.

European Union

Realize the event too late. Cannot do much. Now that Ukraine is under war, EU is bonded to US once more.


Stupid as fk. Lost everything because of some vague promise by US. Let war happen on its own soil due to some stupid and irresponsible politician breaching the status quo.


Cannot do anything. Cannot blame Ukraine as it's the victim. Cannot blame Russia since they are to some degree allies against US. Cannot defend Russia since Ukraine’s sovereign is threatened as a fact. Can blame US but few would listen, and the plot is just too good to believe.

Similar Event in History

Philippine on South China Sea

Stayed calm. Knows its position and is smart enough to avoid being used as pawns of US against China. US did not get anything but swear from Duterte to Obama.

Japan on Fishing Island

Japanese forced to lose its ground. US succeeded to break down the free trading pact between China and Japan.

South Korea on THAAD

Korea was forced to lose its ground. US succeeded to break down the free trading pact between China and South Korea.

Ukraine’s Only Options

Ukraine could be independent as North Korea if it did not give up its nuclear arsenal. Could be stable as Taiwan if it did not join any sides between NATO and Russia.



He is the main one accountable for this event due to lack of insight in foreign affairs and diplomacy status quo. He is not smart enough and has too much goodwill as the leader of a weak nation. He is bound to fail just as Allende in Chile.

If he dies he will become martyr of Ukraine Nationalism and neo-Nazism (ironically as a Jewish), and as an iron proof of Russia invasion. This is the last thing Russia would like to see, but the best thing US wants to see.

If he flees to US without public announcement he would probably be killed by US to fake the previous scenario.

If he flees to US with a public announcement, Ukraine Nationalism would suffer such a hit that Ukraine may just disappear as a country forever. The best thing Russia wants to see.

If he stays and is still the president after the Russian invasion, he will be a National traitor that sell his country to Russia.

In other words, his 'friends' wish he dies and his 'enemies' wish he lives.


He is what he is. He knows what Russia is good at and is not afraid to use its force when necessary. But honestly, he has no choice.

US Politicians

Still so good at manipulating the world.

X3FL – Board Q with 0 Casualty

Boarding a Xenon Q with 0 casualty was easy in TC since one can save load at each deck. Need a little more SL in AP, but was easier than P IIRC. Now it's very hard, but I finally made it after 717 attempts.

So I lower the Q's shield, launch 21 marines, initiate the jump sequence, keep shields low, and save right before boarding pods hit Q. After each reload, once the jump is completed, I open the property menu to watch the marine status, take a screenshot at the hacking stage, save the game, and copy the save to somewhere else.

I wrote a .ahk script to automate the above process, gathering a lot of saves and corresponding screenshots. The screenshots are later processed and clustered using python.

Of all the 793 scenarios recorded, 101 times Q launched a Firestorm Torpedo against me but ironically destroyed itself due to close-range detonation by my anti-missile system.

Of the remaining 692 scenarios, 447 times the marines did not survive till hacking the core. The other 245 (almost) successful scenarios have a distribution of remaining crews as follows at the hacking stage. Note there are occasions when less than 16 marines made it to this stage but were not eliminated.

Only in one scenario, at the 717th attempt, did all 21 crews survive the operation.


Autarky is the characteristic of self-sufficiency, usually applied to societies, communities, states and their economic systems.

Autarky - Wikipedia

I came to know this word as a Nazi Germany economy policy in 1930s. It triggers me deep, as even for an already industrialized country, autarky is still an option.

Design a Space Elvator

TV series Foundation shows a space elevator 911 event. How should a space elevator be designed and what will its collapse look alike?

Consider the space elevator to be a link with linear mass \hat{m}(l) and a total length L.

To have a straight link, everything below the Geosynchronous orbit, or GSO would be rotating too slow to support its own mass. To balance the effect one can choose from 2 sources of support: base reaction from the ground, or tension from above GSO.

The tension of link at height x

T(x) = - F_{r} - \int_0^x{\cfrac{GM\hat{m}}{(R_{e}+l)^2}}dl + \int_0^L{\hat{m}\omega_{e}^2(R_{e}+l)}dl

where R_e is earth radius, \omega_e is earth rotating angular speed, F_r is base reaction force.

The boundry condition

T(L) = 0

Intuitively, a reasonable model will have the ground part in compression, but not that much of the entire gravity of things below synchronous orbit. The link at synchronous orbit will be in tension, so somewhere below there would be a zero force point.

The major payload should be deployed right at GSO, such that it doesn't pose any extra load into the link. Another benefit of the design is that the major payload can always survive any 911 attacks not targeted at it directly by simply cutting itself off the link. In such design, cut the link anywhere will have the lower part fall to Earth and upper part go into space. The TV series made a reasonable assumption.

Though seemingly unavoidable, it is by design inevitable for a (common civillian) building to fail a 911 attack due to economic concern, even a space elevator.

Axial force diagram should look like moment diagram of a cantilever beam under distributed load, and so should a reasonable section design be alike.



莫爸难得上进一回,但全世界都似乎都要跟他作对,很容易怀疑他就是命中注定的loser。从荒诞的层面理解这个故事很爽,但如果仔细想想,莫爸为什么非要象牙白的打印纸,就不难发现,他是想要一个梦幻的开局,一个伟大的起点,最好充满仪式感,能配得上loser翻身的彻底与神奇。可这不是追求完美,而是在寻求拖延。 就像我们最爱的新年计划,或者在20岁,30岁生日许个心愿,仿佛买入下一个节点,一切都会突然改变,人会变得特别上进,事情会变得特别顺。我们喜欢这种仪式感,几乎每年都会来一次,道理和莫爸非要用象牙白的纸类似,往往是对现状不满或者焦虑,所以才期待一个伟大的转折。因为细小的进步很难安抚人心,它必须足够伟大才能消除焦虑。 即使找到了象牙白的简历纸,我想莫爸还是会找各种事情“刁难”自己,这样他就能把失败甩锅给这个世界。所以并不是他以努力全世界都跟着作对,为是他自己跟自己作对。冰冻三尺,非一日之寒。他幻想着一把大火给自己解冻,可有看不起脚下的爝火微光。




仪式 举行典礼的程序、形式 ——现代汉语词典
















Zhejiang University Network

Had a chat with one of the local campus network admin, here is some of what I learned about the Zhejiang University network

  • the entire lab building is merely connected with 2 1-Gbps links
  • the new campus WIFI is restricted to 30 Mbps as requested by old main campus leader 'to ensure consistency'
  • office table network switches are trash with only 100 Mbps link speed
  • private router can cause DHCP problems thus DHCP should always be turned off, or they will ban the mac address
  • private router is against regulation as security might be breached that some connection can not be traced
  • all records are preserved permanently for security purpose
  • all connections to campus network can be traced to someone who is responsible
    • common link for sure can be traced to the account that is using it
    • direct link (static ip) can be traced to the applicant
    • most, if not all, direct link is bound to the device mac address
  • proxy service is detected using self developed software, through various techniques including using ip range pool











Project: Terrain Modelling

This is a sub project of the ongoing project: Hengjin Villiage Plan.

Terrain Model Report

DEM data source

GoogleEarth - RenderDoc - Blender not seamless, unable to use

SketchUp - Digital Globe

low resolution

picture 1

Dataset: ASTGTMV003_N29E121

DOI 10.5067/ASTER/ASTGTM.003 earthdata 2000-03-01 00:00:00 - 2013-11-30 23:59:59 resolution of 1 arc second (approximately 30 meter horizontal posting at the equator)

picture 2

Dataset: ALPSRP133840570-RTC_HI_RES,RTC_HI_RES) earthdata 2008-07-29 14:21:47 - 2008-07-29 14:21:55 resolution of 12m

picture 3

Satalite: TerraSAR-X region not found

image data source

SketchUp - Digital Globe

Photoshop: remove excessive water print, and additional drawing Illustrator: vectorization caffe: scale up resolution

Satalite: Worldview-3 resolution of 0.3m proposal required, need waiting within 14 days owned by digital globe so potentially we may have already get it

Satalite: 高分二号 resolution of 0.8m 要钱 分辨率不如Worldview-3

Turing machine on Hilbert’s question on decidability

Math Has a Fatal Flaw - YouTube

Is it possible to tell beforehand if a program will halt or not on a particular input?

Turing's claim (or what Veritasium claims to be his claim)

let p(i) be any program with its inputs

assume h(p, i) satisfy the requirement, that it tells beforehand if a program will halt or not on a particular input, such that

h(p, i) = \begin{cases} \text{WILL\_HALT}, & \text{if } p(i) \text{ will halt}\\ \text{WILL\_NOT\_HALT}, & \text{if } p(i) \text{ will not halt} \end{cases}

let \hat{h} be

\hat{h}(p, i) = \begin{cases} \text{[infinite loop]}, & \text{if } h(p, i) = \text{WILL\_HALT}\\ 0, & \text{if } h(p, i) = \text{WILL\_NOT\_HALT} \end{cases}

consider h(\hat{h}, \hat{h})

h(\hat{h}, \hat{h}) = \begin{cases} \text{WILL\_HALT}, & \text{if } \hat{h}(\hat{h}) \text{ will halt}\\ \text{WILL\_NOT\_HALT}, & \text{if } \hat{h}(\hat{h}) \text{ will not halt} \end{cases}

or equivalently

h(\hat{h}, \hat{h}) = \begin{cases} \text{WILL\_HALT}, & \text{if } h(\hat{h}) = \text{WILL\_NOT\_HALT}\\ \text{WILL\_NOT\_HALT}, & \text{if } h(\hat{h}) = \text{WILL\_HALT} \end{cases}

The problem is, \hat{h}(\hat{h}) and h(\hat{h}) does not exist as \hat{h} and h takes two parameters, and there is no reason to assume (\hat{h}) = (\hat{h}, \hat{h}), leaving us no contradiction in the end.

The fix

To construct the paradox, we need to lower the input numbers. Instead of \hat{h} we define

\tilde{h}(p) = \begin{cases} \text{[infinite loop]}, & \text{if } h(p, p) = \text{WILL\_HALT}\\ 0, & \text{if } h(p, p) = \text{WILL\_NOT\_HALT} \end{cases}


h(\tilde{h}, \tilde{h}) = \begin{cases} \text{WILL\_HALT}, & \text{if } \tilde{h}(\tilde{h}) \text{ will halt}\\ \text{WILL\_NOT\_HALT}, & \text{if } \tilde{h}(\tilde{h}) \text{ will not halt} \end{cases}

or equivalently

h(\tilde{h}, \tilde{h}) = \begin{cases} \text{WILL\_HALT}, & \text{if } h(\tilde{h}, \tilde{h}) = \text{WILL\_NOT\_HALT}\\ \text{WILL\_NOT\_HALT}, & \text{if } h(\tilde{h}, \tilde{h}) = \text{WILL\_HALT} \end{cases}

Philosophy, physics, and other thoughts

Until I figure the fix out I thought Veritasium is making fake assertions and baiting, turned out he's just been careless, and a paradox does exist.

The logic behind the problem is that, if there exists a program that can tell beforehand whether any problem has a solution, it cannot tell beforehand whether itself has a solution, thus vetoes its own existence.

An analogy would be, if a predictor exists, and we do adversely to whatever it predicts, then its prediction is wrong, and we conclude the predictor does not exist.

Now in terms of predictor people's been creative that in terms of whether things happen at a given future time, it may provide a possibility instead of a definite binary happens or not. The result does not collapse until the given future time, and the behavior of observation does have an influence over the outcome since we can now alternate the predicted future (in forms of possibility). This possibility model solves all the paradox mentioned above.

Back port the possibility model into the problem, there might be a program that can tell beforehand the possibility of whether any program has a solution (with further limits on observer) which is useless though.

The conclusion, however, does not necessarily escalate to 'whether all problems has a solution' since a problem does not necessarily equal a turing machine program. It does, imho, might escalte to 'whether all problems has a definite solution', as is in coherence with quantum physics.

Though I wonder whether mathematicians are satisfied with such conclusion like 'Goldbach conjecture' has a 99.9999... possibility to be true.

On the other hand, an interesting research direction is to prove that 'Goldbach conjecture' is impossible to prove.

用粗野或恶意的话侮辱人:~街|张嘴就~。 斥责:他爹~他不长进。 -- 现代汉语词典



我认为情绪的宣泄与斥责,可以咒骂,但不宜有侮辱之意。虽然骂大多只是情绪的宣泄,但其必有来由。例如“傻逼”“智障”,不见得施法对象就真是“弱智”,但多有嫌弃“幼稚”“naive, too young”之意。在这一方面,长者可谓道行颇深。骂人幼稚,好歹还有长进的空间。


有些骂,看似侮辱,实则,确实侮辱。鲁迅先生曾专就此写过一篇杂文《论“他妈的!”》3。先生认为国骂出处或无据可考,但北魏有邢子才“卿何必姓王?”,颇有骂人仰仗门第之意。这解读多少与先生反封建的社会背景有关。现在有人再讲“他妈的”,含义基本等同于“肏他妈的”。放到白左嘴里这大概可以解读成中国人歧视侮辱女性了,当然他们自己也有"mother fucker",倒是巧合?回到国骂本身,倘若当面骂人“肏你妈的”,不见得真要行不轨之事,但侮辱之意甚矣。



Chengdu Trip

20210726 Chengdu

First impression, Chengdu feels just like any costal city of East China, with modern CBD, railway station, and subway. Living cost seems somehow lower though.

Food is not so good as one would normally claim, possibly due to my bad strategy to try to get accustomed to authentic local food. However some dessert does impress me as I had my first taste on sweet jellied Tofu, very much like pudding.

Local city feels like a strange combination of 2020 East coast CBD with 2000 East coast streets. Prostitutes advertisements are everywhere in hotel, and occasionally I can see one or two of them sharing an elevator.

The elder generally speaks only local accent which is a trouble for me. Good for me that my girlfriend can understand them quite well.

There has been an effort to modernize, or to renovate old streets as tourist spots all over China. What surprised me is that old Chengdu streets, feels just like any East China old street.

Panda, as one of the most famous local cultural element, can be seen everywhere in the city, i.e. posters, sculptures, clothes. Some of these sculptures are really interesting, and the one really impressed me was one built right in the middle of CBD, right on top of one building, featuring a climbing pose.

20210801 Dujiangyan

Ancient irrigation system.

Refer to as a general tour plan. Nothing too bad, yet nothing exceeding expectation either.

20210801 Qingchengshan

If I may say, just as Qingchengshan itself is a mountain developed for religious purpose, the best, and most interesting scenery, is local people.

The 2nd Civil Engineering Computing and Simulation Technology Academic Conference

I would not put my half organized notes here.

I met some of the greatest Chinese scholars in the field. Watched their report, and found myself at a very strange position.

I love computing and simulation technology, but the deeper it goes the more clear its boundry is - technology is technology, civil engineering is engineering, not science.

Changsha Trip

True Fans Changsha Culture and Art Center, by Zaha Hadid.

A true fans sees him everywhere.

20210509 College of Civil Engineering, Hunan University

Odd enough, the metro exit reads 'College of Civil Engineering, Hunan University' instead of just 'Hunan University', despite the entire campus is just outside of the exit and College of Civil Engineering is the one most far from the exit.

San Francisco Night Drive

Night drive with Han Li, Xin Chen, and Siqi Yao.

For the first time I found out that Lombard Street exists more than just in GTA. > <

20210130201505 San Francisco - Oakland Bay Bridge from Treasure Island 20210130201505 San Francisco - Oakland Bay Bridge from Treasure Island

20210130210724 San Francisco - Oakland Bay Bridge from Inside 20210130210724 San Francisco - Oakland Bay Bridge from Inside

Chrome Dark Scroll Bar

Chrome now supports dark scroll bar as Github has implemented. After careful search and debug I finally located 2 syntax for its implementation, being:

A HTML meta tag telling Chrome supported color-schemes with preference by order. Chrome users with system-wide light/dark theme will find it respect this tag on page reload. The light theme remains what it was, while the dark theme features a default pure black background and pure white font color, with other colors like purple for hyperlinks.

<meta name="color-scheme" content="light dark">

A CSS property which can override previous meta tag and works without reloading the page

:root {
  color-scheme: dark;


Improved dark mode default styling with the color-scheme CSS property and the corresponding meta tag

Tall Grass

202101202110 Tall Grass

Night of first trials on tennis and skateboard, taught by and practised with Xinyu Hu, Han Li, Zhirong Lin, and Xin Chen.

Virtualize Dual-boot Linux

Comparing with WSL2

  • Pro
    • Allow maximum performance when using physical machine
    • Have Native GUI which can be accessed using VirtualBox
    • Native disk operation performance under virtual machine
  • Con
    • No app optimization and support in Windows, e.g. vscode, cuda (but vscode has ssh feature, and you have native linux cuda under physical machine)
    • Mapped file in RAM is not managed by Windows, naturally, thus requiring a larger RAM (Your RAM stores mapped files from both host Windows and VM Linux now)
  • Even
    • Other performance under windows, e.g disk operation across systems (using SMB)

Chrome OS on Surface Pro 7



except # Not Working

Not Working

  • Multi-touch Finger Input (Single-touch works)
  • Stylus Input
  • Camera
  • Surprise, dark mode hasn't been implemented in Chrome OS 87!

Have Problem Working

Speaker will make hissing noises with headphone injected


Chrome OS cannot be installed directly to PC due to hardware compatibility. Some hardware, e.g. the Intel Precise Touch Screen of Surface Pro, even requires special driver. Moreover, Chrome OS, or Android, are built to install on the entire disk (not a partition).

'brunch' is a framework project featuring these problems by including support for PC hardwares and installing Chrome OS on a .img disk mirror file.


sebanc/brunch: Boot ChromeOS on x86_64 PC (supports most Intel CPU/GPU or AMD Stoney Ridge)

Rammus recovery bin from CrOS Updates Serving

Bottle neck upstream repo

linux-surface/iptsd: Userspace daemon for Intel Precise Touch & Stylus

Install script

I use WSL to pack up the '.img' file. Due to the warning given by brunch readme, I made a special partition, a 32 GB NTFS 'G:\', i.e. '/mnt/g/' in wsl for safety concern. The img size is thus set at 31 (GB).

The reason to use NTFS is to facilitate disk operation in Windows. An EXT4 file system will work too, but not FAT32 due to lack of support of large file.

sudo apt-get install pv
sudo apt-get install cgpt
sudo bash -src chromeos_13505.73.0_rammus_recovery_stable-channel_mp-v2.bin -dst /mnt/g/chromeos.img -s 31;


Need to disable Secure Boot and Bitlocker first.

Turning Secure Boot back on is an easy method to disable GRUB - thus booting directly into Windows.

I use grub2win for multi-boot. Add the boot code generated by brunch (next to the generated '.img' file) to grub.cfg to add the Chrome OS boot entry, and specify options=ipts in kernel parameters to enable touchscreen input.


Follow instructions of BiteDasher/brcr-update: Script to update Chrome OS installed using the brunch framework

KaTeX with VSCode, Jekyll, and WordPress Markdown

I use KaTeX in VSCode extension Markdown All in One for notes and homework. It's by far the easiest and most flexible way.

Markdown is such a markup language (see the paradox? lol) without a widely-accepted, strong official organization regularizing its syntax and grammar. Typical standards includes:

Implementation of Javascript libraries into Markdown, such as KaTeX, is done independently by Markdown processors, thus creating even more variants of syntax and grammar.

In an attempt to use the same syntax and grammar throughout my Markdown documents, i.e KaTeX with VSCode, Jekyll, and WordPress Markdown, and considering the possible transplantation to LaTeX, I adopt the following configuration for most consistent experience.

Celestial Coordinate Systems

This work is from part of UCB CS289A 2020 Fall Project S Final. See Github repo for more information.

A physical model is evaluated so that we can understand the problem more properly.

Solar-centered ecliptic coordinate system

Solar-centered ecliptic coordinate system is centered at the sun, using spring equinox as x+ or polar axis, ecliptic as xy plane.

Earth location (polar)

\mathbf{x}_e = (r_e, \theta_e, 0)


\theta_e = \frac{2 \pi}{T_{ey}} t + \theta_{e0}

or (dirichlet)

\mathbf{x}_e = \begin{bmatrix} r_e \cos{(\cfrac{2 \pi}{T_{ey}} t + \theta_{e0})}\\ r_e \sin{(\cfrac{2 \pi}{T_{ey}} t + \theta_{e0})}\\ 0\\ \end{bmatrix}

other planets can have a similar definition.

Earth-centered ecliptic coordinate system

Solar-centered ecliptic coordinate system is centered at the earth, using spring equinox as x+ or polar axis, ecliptic as xy plane.

Equatorial coordinate system

Equatorial coordinate system is centered at the earth, using spring equinox as x+ or polar axis, equator as xy plane.

Planets location in such system is defined as right ascension \alpha and declination \delta,

as (polar)

\mathbf{X}_p = (R_p, \frac{\pi}{2} - \delta, \alpha)

as we normally do with spherical coordinate system (r,\theta,\phi)

or (dirichlet)

\mathbf{X}_p = \begin{bmatrix} R_p \cos\delta \cos\alpha\\ R_p \cos\delta \sin\alpha\\ R_p \sin\delta\\ \end{bmatrix}

Horizontal coordinate system

Horizontal coordinate system is centered at the observer, using local north as x+ or polar axis, local vertical up direction as z+.

Planets location in such system is defined as azimuth A and altitude a,

as (polar)

\hat \mathbf{X}_p = (R_p, \frac{\pi}{2} - a, A)

as we normally do with spherical coordinate system (r,\theta,\phi)

or (dirichlet)

\hat \mathbf{X}_p = \begin{bmatrix} R_p \cos a \cos A\\ R_p \cos a \sin A\\ R_p \sin a\\ \end{bmatrix}

Coordinate transformation

It is easy to transform between the solar-centered ecliptic coordinate system and the earth-centered ecliptic coordinate system. A planet with coordinate \mathbf{x}_p in solar-centered ecliptic coordinate system is at \mathbf{x}_p - \mathbf{x}_e in earth-centered ecliptic coordinate system.

\mathbf{x}_p - \mathbf{x}_e = \begin{bmatrix} r_p \cos{(\cfrac{2 \pi}{T_{py}} t + \theta_{p0})} - r_e \cos{(\cfrac{2 \pi}{T_{ey}} t + \theta_{e0})}\\ r_p \sin{(\cfrac{2 \pi}{T_{py}} t + \theta_{p0})} - r_e \sin{(\cfrac{2 \pi}{T_{ey}} t + \theta_{e0})}\\ 0\\ \end{bmatrix}

transformation from the earth-centered ecliptic to equatorial coordinate system 1

\begin{bmatrix} x_{\text{equatorial}}\\ y_{\text{equatorial}}\\ z_{\text{equatorial}}\\ \end{bmatrix} = \begin{bmatrix} 1 & 0 & 0\\ 0 & \cos \varepsilon & -\sin \varepsilon \\ 0 & \sin \varepsilon & \cos \varepsilon \\ \end{bmatrix} \begin{bmatrix} x_{\text{ecliptic}}\\ y_{\text{ecliptic}}\\ z_{\text{ecliptic}}\\ \end{bmatrix}

where ecliptic obliquity


so we have

\begin{aligned} \begin{bmatrix} R_p \cos\delta \cos\alpha\\ R_p \cos\delta \sin\alpha\\ R_p \sin\delta\\ \end{bmatrix} &= \begin{bmatrix} 1 & 0 & 0\\ 0 & \cos \varepsilon & -\sin \varepsilon \\ 0 & \sin \varepsilon & \cos \varepsilon \\ \end{bmatrix} \begin{bmatrix} r_p \cos{(\cfrac{2 \pi}{T_{py}} t + \theta_{p0})} - r_e \cos{(\cfrac{2 \pi}{T_{ey}} t + \theta_{e0})}\\ r_p \sin{(\cfrac{2 \pi}{T_{py}} t + \theta_{p0})} - r_e \sin{(\cfrac{2 \pi}{T_{ey}} t + \theta_{e0})}\\ 0\\ \end{bmatrix} \\ &= \begin{bmatrix} r_p \cos{(\cfrac{2 \pi}{T_{py}} t + \theta_{p0})} - r_e \cos{(\cfrac{2 \pi}{T_{ey}} t + \theta_{e0})}\\ \cos \varepsilon (r_p \sin{(\cfrac{2 \pi}{T_{py}} t + \theta_{p0})} - r_e \sin{(\cfrac{2 \pi}{T_{ey}} t + \theta_{e0})})\\ \sin \varepsilon (r_p \sin{(\cfrac{2 \pi}{T_{py}} t + \theta_{p0})} - r_e \sin{(\cfrac{2 \pi}{T_{ey}} t + \theta_{e0})})\\ \end{bmatrix} \end{aligned}

transformation from equatorial to horizontal coordinate system 2

\cos A\cdot \cos a=-\cos \phi \cdot \sin \delta +\sin \phi \cdot \cos \delta \cdot \cos H
\sin A\cdot \cos a=\cos \delta \cdot \sin H
\sin a=\sin \phi \cdot \sin \delta +\cos \phi \cdot \cos \delta \cdot \cos H


\begin{aligned} \begin{bmatrix} \cos A\cdot \cos a\\ \sin A\cdot \cos a\\ \sin a\\ \end{bmatrix} &= \begin{bmatrix} \sin \phi & 0 & -\cos \phi\\ 0 & 1 & 0\\ \cos \phi & 0 & \sin \phi \\ \end{bmatrix} \begin{bmatrix} \cos\delta \cos H\\ \cos\delta \sin H\\ \sin\delta\\ \end{bmatrix} \\ \end{aligned}

where hour angle3

H(t,\alpha) = GST(t) + \lambda - \alpha

One of the final goal of this project is to predict A and a with t, given longitude \lambda and latitude \phi under specific model, which we are to try explaing.


  • Planets are actually in ellipse orbits instead of circle ones and z is not to be precise, here we made some simplification just to show the complexity of the problem
  • A slow motion of Earth's axis, precession, causes a slow, continuous turning of the coordinate system westward about the poles of the ecliptic, completing one circuit in about 26,000 years.


  1. Ecliptic coordinate system - Wikipedia, 

  2. Horizontal coordinate system - Wikipedia, 

  3. Hour angle - Wikipedia, 

Core Concepts in FEA


Before we start, some basic mathematic theorem12.


∇·v = v_{i,i}
∇·T = T_{ij,i} e_j

Gradient (dim+1)

∇\phi = \phi_{,i} e_i
∇v = v_{i,j} e_i⊗e_j
∇T = T_{ij,k} e_i⊗e_j⊗e_k

Curl (dim=)

∇ × v =ε_{ijk} v_{j,i} e_k
∇ × T =ε_{ijk} T_{mj,i} e_k⊗e_m

The product rule of differentiation

\because \bm{σ}·\bm{\nu} = \bm{σ}_{ij}\bm{\nu}_j e_i
\therefore ∇·(\bm{σ}·\bm{\nu}) = (\bm{σ}_{ij}\bm{\nu}_j)_{,i} = \bm{σ}_{ij,i}\bm{\nu}_j + \bm{σ}_{ij}\bm{\nu}_{j,i}


(∇·\bm{σ})·\bm{\nu} = \bm{σ}_{ij,i} \bm{\nu}_j
∇\bm{\nu} : \bm{σ} = \bm{\nu}_{i,j}\bm{σ}_{ji}

or as Prof. Zohdi suggested

∇\bm{\nu} : \bm{σ} = \bm{\nu}_{i,j}\bm{σ}_{ij}

but since \bm{σ} is symmetric

\bm{σ}_{ij} = \bm{σ}_{ji}


\tag{1} ∇·(\bm{σ}·\bm{\nu}) = (∇·\bm{σ})·\bm{\nu} + ∇\bm{\nu} : \bm{σ}

Divergence Theorem

∫_{∂R} \phi n dA = ∫_{R} ∇·\phi dV
\tag{2} ∫_{∂R} \bm{v}·n dA = ∫_{R} ∇·\bm{v} dV
∫_{∂R} \bm{T} n dA = ∫_{R} ∇·\bm{T} dV


∫_{∂R} \phi n_i dA = ∫_{R} \phi_{,i} dV
∫_{∂R} v_i n_i dA = ∫_{R} v_{i,i} dV
∫_{∂R} T_{ij}n_j dA = ∫_{R} T_{ij,j} dV

Stokes theorem

∫_{C} \phi d\bm{x} = ∫_{S} n × ∇\phi dA
∫_{C} v·d\bm{x} = ∫_{S} n·∇×v dA
∫_{C} T d\bm{x} = ∫_{S} (∇×T)^T n dA


∫_{C} \phi dx_i = ∫_{S} ε_{ijk} n_j \phi_{,k} dA
∫_{C} v_i dx_i = ∫_{S} n_i ε_{ijk} v_{k,j} dA
∫_{C} T_{ij} dx_j = ∫_{S} ε_{jpq} T_{iq,p} n_j dA


The SMALL deformation of the body is governed by (strong form):



\bm{σ} = \bm{IE}:∇\bm{u}


\bm{f} = ρ\bm{g}


∇·\bm{σ} + \bm{f} = 0

so we can write

∫_Ω (∇·\bm{σ} + \bm{f} ) · \bm{\nu} dΩ = 0

using (1)

∫_Ω (∇·(\bm{σ}·\bm{\nu})-∇\bm{\nu}:\bm{σ}) dΩ + ∫_Ω \bm{f}·\bm{\nu} dΩ = 0

using (2)

∫_Ω ∇\bm{\nu}:\bm{σ} dΩ = ∫_Ω \bm{f}·\bm{\nu} dΩ + ∫_{∂Ω} \bm{σ}·\bm{\nu}·n dA


\bm{t} = \bm{σ}·\bm{n}


∫_Ω ∇\bm{\nu}:\bm{σ} dΩ = ∫_Ω \bm{f}·\bm{\nu} dΩ + ∫_{Γ_t} \bm{t}·\bm{\nu} dA

so we have the weak form

\begin{array}{lcr} \text{Find }\bm{u}, \bm{u}|_{Γ_u} = \bm{u}^* \text{, such that }∀\bm{\nu}, \bm{\nu}|_{Γ_u}= 0 \\ \displaystyle∫_Ω ∇\bm{\nu}:\bm{IE}:∇\bm{u} dΩ = ∫_Ω \bm{f}·\bm{\nu} dΩ + ∫_{Γ_t} \bm{t}·\bm{\nu} dA \end{array}

where u^ is the applied boundary displacement on Γ_u, t = t^ on Γ_t

since the integrals must be finite, we improve the weak form as below

\begin{array}{lcr} \text{Find }\bm{u} ∈ \bm{H}^1(Ω), \bm{u}|_{Γ_u} = u^* \text{, such that }∀\bm{\nu} ∈ \bm{H}^1(Ω), \bm{\nu}|_{Γ_u}= 0 \\ \displaystyle∫_Ω ∇\bm{\nu}:\bm{IE}:∇\bm{u} dΩ = ∫_Ω \bm{f}·\bm{\nu} dΩ + ∫_{Γ_t} \bm{t}·\bm{\nu} dA \end{array}


\bm{H}^1(Ω) \vcentcolon= [H^1(Ω)]^3

explained as below

similar to the definition of u ∈ H^1(Ω) which states

u ∈ H^1(Ω) \text{ if } ||u||_{H^1(Ω)}^2 \vcentcolon= ∫_Ω u_{,j}u_{,j} dΩ + ∫_Ω uudΩ

the definition of \bm{u} ∈ \bm{H}^1(Ω) states as below

\bm{u} ∈ \bm{H}^1(Ω) \text{ if } ||\bm{u}||_{\bm{H}^1(Ω)}^2 \vcentcolon= ∫_Ω u_{i,j}u_{i,j} dΩ + ∫_Ω u_iu_idΩ


should \bm{u}^* be different from the applied boundary displacement on Γ_u, weak form can be stated as below

\tag{3} \begin{array}{lcr} \text{Find }\bm{u} ∈ \bm{H}^1(Ω) \text{, such that }∀\bm{\nu} ∈ \bm{H}^1(Ω) \\ \displaystyle∫_Ω ∇\bm{\nu}:\bm{IE}:∇\bm{u} dΩ = ∫_Ω \bm{f}·\bm{\nu} dΩ + ∫_{Γ_t} \bm{t}·\bm{\nu} dA + P^\star∫_{Γ_u} (\bm{u}^*-\bm{u})·\bm{\nu} dA \end{array}


\begin{array}{lcr} \text{Find }\bm{u} ∈ \bm{H}^1(Ω) \text{, such that }∀\bm{\nu} ∈ \bm{H}^1(Ω) \\ \displaystyle∫_Ω \nu_{i,j} IE_{ijkl} u_{k,l} dΩ = ∫_Ω f_i \nu_i dΩ + ∫_{Γ_t} t_i \nu_i dA + P^\star∫_{Γ_u} u^*_i \nu_i - u_i \nu_i dA \end{array}

where the (penalty) parameter P^\star is a large positive number.


To have

\begin{cases} \hat{\phi}_i(\zeta_1,\zeta_2,\zeta_3) = 1 &\text{ , } \zeta_1=\zeta_{i1},\zeta_2=\zeta_{i2},\zeta_3=\zeta_{i3} \\ \hat{\phi}_i(\zeta_1,\zeta_2,\zeta_3) = 0 &\text{ , } \text{others} \end{cases}

for each \hat{\phi}_i 8 functions (for each of the 8 points) with 8 unknowns, aka. \zeta_1^m \zeta_2^n \zeta_3^k where m,n,k=0,1 can be derived, leading to the only solution as following

\begin{cases} \hat{\phi}_1 = \frac{1}{8} (1-\zeta_1) (1-\zeta_2) (1-\zeta_3) \\ \hat{\phi}_2 = \frac{1}{8} (1+\zeta_1) (1-\zeta_2) (1-\zeta_3) \\ \hat{\phi}_3 = \frac{1}{8} (1+\zeta_1) (1+\zeta_2) (1-\zeta_3) \\ \hat{\phi}_4 = \frac{1}{8} (1-\zeta_1) (1+\zeta_2) (1-\zeta_3) \\ \hat{\phi}_5 = \frac{1}{8} (1-\zeta_1) (1-\zeta_2) (1+\zeta_3) \\ \hat{\phi}_6 = \frac{1}{8} (1+\zeta_1) (1-\zeta_2) (1+\zeta_3) \\ \hat{\phi}_7 = \frac{1}{8} (1+\zeta_1) (1+\zeta_2) (1+\zeta_3) \\ \hat{\phi}_8 = \frac{1}{8} (1-\zeta_1) (1+\zeta_2) (1+\zeta_3) \end{cases}


\bm{IE} has the following symmetries 23

IE_{ijkl} = IE_{klij} = IE_{jikl} = IE_{ijlk}

allowing us to rewrite (3) in a more compact matrix form

\tag{4} \begin{aligned} ∫_Ω ([\bm{D}]\{\bm{\nu}\})^T [\bm{IE}] ([\bm{D}]\{\bm{u}\}) dΩ = &∫_Ω \{\bm{\nu}\}^T\{\bm{f}\} dΩ \\ &+ ∫_{Γ_t} \{\bm{\nu}\}^T\{\bm{t}^*\} dA \\ &+ P^\star∫_{Γ_u} \{\bm{\nu}\}^T\{\bm{u}^*-\bm{u}\} dA \end{aligned}


\tag{5} [\bm{D}] \vcentcolon = \begin{bmatrix} \cfrac{∂}{∂x_1} & 0 & 0 \\ 0 & \cfrac{∂}{∂x_2} & 0 \\ 0 & 0 & \cfrac{∂}{∂x_3} \\ \cfrac{∂}{∂x_2} & \cfrac{∂}{∂x_1} & 0 \\ 0 & \cfrac{∂}{∂x_3} & \cfrac{∂}{∂x_2} \\ \cfrac{∂}{∂x_3} & 0 & \cfrac{∂}{∂x_1} \\ \end{bmatrix}, \{\bm{u}\} \vcentcolon = \begin{Bmatrix} u_1 \\ u_2 \\ u_3 \\ \end{Bmatrix}, \{\bm{f}\} \vcentcolon = \begin{Bmatrix} f_1 \\ f_2 \\ f_3 \\ \end{Bmatrix}, \{\bm{t}^*\} \vcentcolon = \begin{Bmatrix} t^*_1 \\ t^*_2 \\ t^*_3 \\ \end{Bmatrix},

and [\bm{IE}] is the elastic stiffness matrix of the material.

[\bm{IE}] \vcentcolon = \begin{bmatrix} IE_{1111} & IE_{1122} & IE_{1133} & IE_{1112} & IE_{1123} & IE_{1113} \\ IE_{2211} & IE_{2222} & IE_{2233} & IE_{2212} & IE_{2223} & IE_{2213} \\ IE_{3311} & IE_{3322} & IE_{3333} & IE_{3312} & IE_{3323} & IE_{3313} \\ IE_{1211} & IE_{1222} & IE_{1233} & IE_{1212} & IE_{1223} & IE_{1213} \\ IE_{2311} & IE_{2322} & IE_{2333} & IE_{2312} & IE_{2323} & IE_{2313} \\ IE_{1311} & IE_{1322} & IE_{1333} & IE_{1312} & IE_{1323} & IE_{1313} \\ \end{bmatrix}

Further rewrite {\bm{u}^h}

\tag{6} \{\bm{u}^h\} = [\phi]\{\bm{a}\}


\{\bm{a}\} \vcentcolon = \begin{Bmatrix} a_1 \\ a_2 \\ a_3 \\ .\\ .\\ .\\ a_{3N}\\ \end{Bmatrix}, [\phi] \vcentcolon = \begin{bmatrix} \phi_1 & \phi_2 & ... & \phi_N & & & & & & & & \\ & & & & \phi_1 & \phi_2 & ... & \phi_N & & & & \\ & & & & & & & & \phi_1 & \phi_2 & ... & \phi_N \\ \end{bmatrix},

choose \bm{\nu} with the same basis, but a different linear combination

\tag{7} \{\bm{\nu}^h\} = [\phi]\{\bm{b}\}

with (6),(7) we can rewrite (4)

\tag{8} \begin{aligned} ∫_Ω ([\bm{D}][\phi]\{\bm{b}\})^T [\bm{IE}] ([\bm{D}][\phi]\{\bm{a}\}) dΩ = &∫_Ω ([\phi]\{\bm{b}\})^T\{\bm{f}\} dΩ \\ & + ∫_{Γ_t} ([\phi]\{\bm{b}\})^T\{\bm{t}^*\} dA \\ & + P^\star∫_{Γ_u} ([\phi]\{\bm{b}\})^T\{\bm{u}^*-[\phi]\{\bm{a}\}\} dA \end{aligned}

We can rewrite (8)

\{\bm{b}\}^T \{ [\bm{K}] \{\bm{a}\} - \{\bm{R}\} \} = 0


\tag{9} [\bm{K}] \vcentcolon = ∫_Ω ([\bm{D}][\phi])^T [\bm{IE}] ([\bm{D}][\phi]) dΩ + P^\star∫_{Γ_u} [\phi]^T[\phi] dA
\tag{10} \{\bm{R}\} \vcentcolon = ∫_Ω [\phi]^T\{\bm{f}\} dΩ + ∫_{Γ_t} [\phi]^T\{\bm{t}^*\} dA + P^\star∫_{Γ_u} [\phi]^T\{\bm{u}^*\} dA


[\bm{K}] = \sum_{e=1}^{N_e}{[\bm{K}]^e}

we can rewrite (9),(10) for e=1,2..,N_e

\tag{11} [\bm{K}]^e \vcentcolon = ∫_{Ω_e} ([\bm{D}][\phi])^T [\bm{IE}] ([\bm{D}][\phi]) dΩ_e + P^\star∫_{Γ_{u,e}} [\phi]^T[\phi] dA_e
\tag{12} \{\bm{R}\}^e \vcentcolon = ∫_{Ω_e} [\phi]^T\{\bm{f}\} dΩ_e + ∫_{Γ_{t,e}} [\phi]^T\{\bm{t}^*\} dA_e + P^\star∫_{Γ_{u,e}} [\phi]^T\{\bm{u}^*\} dA_e


Γ_{u,e} = Γ_u ∩ ∂Ω_e
Γ_{t,e} = Γ_t ∩ ∂Ω_e


In 3D,

[\hat\phi] \vcentcolon = \begin{bmatrix} \hat\phi_1 & \hat\phi_2 & ... & \hat\phi_8 & & & & & & & & \\ & & & & \hat\phi_1 & \hat\phi_2 & ... & \hat\phi_8 & & & & \\ & & & & & & & & \hat\phi_1 & \hat\phi_2 & ... & \hat\phi_8 \\ \end{bmatrix}

express [\bm{D}] in terms ζ_1, ζ_2, ζ_3

[D(\phi(x1, x2, x3))] = [\hat D \phi(M_{x_1}(ζ1, ζ2, ζ3),M_{x_2}(ζ1, ζ2, ζ3),M_{x_3}(ζ1, ζ2, ζ3))]

so that

[\hat \bm{D}] = \begin{bmatrix} \cfrac{∂}{ζ_i}\cfrac{ζ_i}{∂x_1} & 0 & 0 \\ 0 & \cfrac{∂}{ζ_i}\cfrac{ζ_i}{∂x_2} & 0 \\ 0 & 0 & \cfrac{∂}{ζ_i}\cfrac{ζ_i}{∂x_3} \\ \cfrac{∂}{ζ_i}\cfrac{ζ_i}{∂x_2} & \cfrac{∂}{ζ_i}\cfrac{ζ_i}{∂x_1} & 0 \\ 0 & \cfrac{∂}{ζ_i}\cfrac{ζ_i}{∂x_3} & \cfrac{∂}{ζ_i}\cfrac{ζ_i}{∂x_2} \\ \cfrac{∂}{ζ_i}\cfrac{ζ_i}{∂x_3} & 0 & \cfrac{∂}{ζ_i}\cfrac{ζ_i}{∂x_1} \\ \end{bmatrix}


[\hat \bm{D}][\hat\phi] = \begin{bmatrix} \cfrac{∂\hat\phi_1}{ζ_i}\cfrac{ζ_i}{∂x_1} & \cfrac{∂\hat\phi_2}{ζ_i}\cfrac{ζ_i}{∂x_1} & ... & \cfrac{∂\hat\phi_8}{ζ_i}\cfrac{ζ_i}{∂x_1} & & & & & & & \\ & & & & \cfrac{∂\hat\phi_1}{ζ_i}\cfrac{ζ_i}{∂x_2} & \cfrac{∂\hat\phi_2}{ζ_i}\cfrac{ζ_i}{∂x_2} & ... & \cfrac{∂\hat\phi_8}{ζ_i}\cfrac{ζ_i}{∂x_2} & & & \\ & & & & & & & & \cfrac{∂\hat\phi_1}{ζ_i}\cfrac{ζ_i}{∂x_3} & \cfrac{∂\hat\phi_2}{ζ_i}\cfrac{ζ_i}{∂x_3} & ... & \cfrac{∂\hat\phi_8}{ζ_i}\cfrac{ζ_i}{∂x_3} \\ \cfrac{∂\hat\phi_1}{ζ_i}\cfrac{ζ_i}{∂x_2} & \cfrac{∂\hat\phi_2}{ζ_i}\cfrac{ζ_i}{∂x_2} & ... & \cfrac{∂\hat\phi_8}{ζ_i}\cfrac{ζ_i}{∂x_2} & \cfrac{∂\hat\phi_1}{ζ_i}\cfrac{ζ_i}{∂x_1} & \cfrac{∂\hat\phi_2}{ζ_i}\cfrac{ζ_i}{∂x_1} & ... & \cfrac{∂\hat\phi_8}{ζ_i}\cfrac{ζ_i}{∂x_1} & & & \\ & & & & \cfrac{∂\hat\phi_1}{ζ_i}\cfrac{ζ_i}{∂x_3} & \cfrac{∂\hat\phi_2}{ζ_i}\cfrac{ζ_i}{∂x_3} & ... & \cfrac{∂\hat\phi_8}{ζ_i}\cfrac{ζ_i}{∂x_3} & \cfrac{∂\hat\phi_1}{ζ_i}\cfrac{ζ_i}{∂x_2} & \cfrac{∂\hat\phi_2}{ζ_i}\cfrac{ζ_i}{∂x_2} & ... & \cfrac{∂\hat\phi_8}{ζ_i}\cfrac{ζ_i}{∂x_2} \\ \cfrac{∂\hat\phi_1}{ζ_i}\cfrac{ζ_i}{∂x_3} & \cfrac{∂\hat\phi_2}{ζ_i}\cfrac{ζ_i}{∂x_3} & ... & \cfrac{∂\hat\phi_8}{ζ_i}\cfrac{ζ_i}{∂x_3} & & & & & \cfrac{∂\hat\phi_1}{ζ_i}\cfrac{ζ_i}{∂x_1} & \cfrac{∂\hat\phi_2}{ζ_i}\cfrac{ζ_i}{∂x_1} & ... & \cfrac{∂\hat\phi_8}{ζ_i}\cfrac{ζ_i}{∂x_1} \\ \end{bmatrix}

with Gaussian Quadrature

\int_0^L{F(x)dx} = \int_{-1}^1{F(x(\zeta))J(\zeta)d\zeta} = \sum_1^G{w_i}F(\zeta_i)J(\zeta_i)

we can rewrite (11),(12)

[\bm{K}]^e = \sum_1^G{\sum_1^G{\sum_1^G{w_q w_r w_s ([\hat \bm{D}][\hat\phi])^T[\hat{\bm{IE}}][\hat \bm{D}][\hat\phi]J}}}+ P^\star\sum_1^G{\sum_1^G{w_q w_r [\phi]^T[\phi] J_s}}
\{\bm{R}\}^e = \sum_1^G{\sum_1^G{\sum_1^G{w_q w_r w_s [\phi]^T\{\bm{f}\} J}}} + \sum_1^G{\sum_1^G{w_q w_r[\phi]^T\{\bm{t}^*\} J_s}} + P^\star\sum_1^G{\sum_1^G{w_q w_r [\phi]^T\{\bm{u}^*\} J_s}}


\bm{F} \vcentcolon= ∇x(ζ_1,ζ_2,ζ_3)
J \vcentcolon= |\bm{F}|


J_s = J\bm{F}^{-T}·\bm{N}·\bm{n}

derived as below

Nanson’s formula

\bm{n} dA_e = J\bm{F}^{-T}·\bm{N} d\hat{Ae}

where A_e is an area of a region in the current configuration, \hat{Ae} is the same area in the reference configuration, and \bm{n} is the outward normal to the area element in the current configuration while \bm{N} is the outward normal in the reference configuration.

multiply \bm{n} on both sides

dA_e = J\bm{F}^{-T}·\bm{N}·\bm{n} d\hat{Ae}


J_s = J\bm{F}^{-T}·\bm{N}·\bm{n}




let the heat flux density4 q

\bm{q} = \bm{IK}⋅∇θ

and let

f = ρs


∇⋅\bm{q} + f = 0

so we can write

\tag{13} ∫_Ω (∇·\bm{q} + f ) · \nu dΩ = 0

now consider

(∇⋅\bm{q})·\nu = q_{i,i}\nu
∇⋅(\bm{q}\nu) = (q_i \nu)_{,i} = q_{i,i}\nu + q_i \nu_{,i}
(∇\nu)·\bm{q} = q_i \nu_{,i}

therefore we can write (13) as

∫_Ω (∇⋅(\bm{q}\nu) - (∇\nu)·\bm{q}) dΩ + ∫_Ω f\nu dΩ= 0
∫_Ω (∇\nu)·\bm{q} dΩ = ∫_Ω f\nu dΩ + ∫_Ω ∇⋅(\bm{q}\nu)

using (2)

∫_Ω (∇\nu)·\bm{q} dΩ = ∫_Ω f\nu dΩ + ∫_{∂Ω} \bm{q}⋅\bm{n} \nu dA

so we have the weak form

\begin{array}{lcr} \text{Find }θ ∈ H^1(Ω), θ|_{Γ_θ} = θ^* \text{, such that }∀\nu ∈ H^1(Ω), \nu|_{Γ_θ}= 0 \\ \displaystyle∫_Ω (∇\nu)·\bm{IK}⋅∇θ dΩ = ∫_Ω f \nu dΩ + ∫_{∂Ω} \bm{q}⋅\bm{n} \nu dA \end{array}


should θ^* be different from the applied boundary displacement on Γ_θ, weak form can be stated as below

\tag{14} \begin{array}{lcr} \text{Find }θ ∈ H^1(Ω), θ|_{Γ_θ} = θ^* \text{, such that }∀\nu ∈ H^1(Ω), \nu|_{Γ_θ}= 0 \\ \displaystyle∫_Ω (∇\nu)·\bm{IK}⋅∇θ dΩ = ∫_Ω f \nu dΩ + ∫_{∂Ω} \bm{q}⋅\bm{n} \nu dA + P^\star∫_{Γ_θ} (θ^*-θ) \nu dA \end{array}

where the (penalty) parameter P^\star is a large positive number.


same as 3


rewrite θ^h

\tag{15} θ^h = [\phi]\{\bm{a}\} = \phi_i a_i


\{\bm{a}\} \vcentcolon = \begin{Bmatrix} a_1 \\ a_2 \\ a_3 \\ .\\ .\\ .\\ a_{N}\\ \end{Bmatrix}, [\phi] \vcentcolon = \begin{bmatrix} \phi_1 & \phi_2 & ... & \phi_N \end{bmatrix},

choose \bm{\nu} with the same basis, but a different linear combination

\tag{16} \nu^h = [\phi]\{\bm{b}\} = \phi_j b_j

with (15),(16) we can rewrite (14)

\tag{17} \begin{aligned} ∫_Ω (∇[\phi]\{\bm{b}\})·\bm{IK}⋅∇[\phi]\{\bm{a}\} dΩ = & ∫_Ω f [\phi]\{\bm{b}\} dΩ \\ & + ∫_{∂Ω} \bm{q}⋅\bm{n} [\phi]\{\bm{b}\} dA \\ & + P^\star∫_{Γ_θ} (θ^*-[\phi]\{\bm{a}\})·[\phi]\{\bm{b}\} dA \end{aligned}

We can rewrite (17)

\{\bm{b}\}^T \{ K \{\bm{a}\} - \{\bm{R}\} \} = 0


\tag{18} K \vcentcolon = ∫_Ω (∇[\phi])·\bm{IK}⋅∇[\phi] dΩ + P^\star∫_{Γ_θ} [\phi]^T[\phi] dA
\tag{19} \{\bm{R}\} \vcentcolon = ∫_Ω [\phi]^Tf dΩ + ∫_{∂Ω} [\phi]^T\bm{q}⋅\bm{n} dA + P^\star∫_{Γ_θ} [\phi]^Tθ^* dA


K= \sum_{e=1}^{N_e}K^e

we can rewrite (18),(19) for e=1,2..,N_e

K^e \vcentcolon = ∫_{Ω_e} (∇[\phi])·\bm{IK}⋅∇[\phi] dΩ_e + P^\star∫_{Γ_{u,e}} [\phi]^T[\phi] dA_e
\{\bm{R}\}^e \vcentcolon = ∫_{Ω_e} [\phi]^Tf dΩ_e + ∫_{∂Ω,e} [\phi]^T\bm{q}⋅\bm{n} dA_e + P^\star∫_{Γ_{u,e}} [\phi]^Tθ^* dA_e


Γ_{θ,e} = Γ_θ ∩ ∂Ω_e


Key difference is that the diemsion of the equations derived for thermodynamics are generally lower than those for linear elasticity.

This is because θ and s are scalers rather than vectors as \bm{u} and \bm{g}, and \bm{IK} is a second order tensor rather than a forth order tensor as \bm{IE}.


  1. Tensor derivative (continuum mechanics) Cartesian coordinates, 

  2. Lallit Anand and Sanjay Govindjee, 2019, Introduction to Continuum Mechanics of Solid 

  3. Allan F. Bower, 2012, Applied Mechanics of Solids, Chapter 3 

  4. Thermal conduction differential form, 

Anti Chinese Sentiment

'Unfavorable views' of China reach historic highs, new report finds


It's been an issue since several years ago, or maybe longer as Wikipedia suggests. Last year when I was taking LP380 I discussed this problem with Prof. Ellan, a democrat. As most left-wing Americans would recognize such an issue and blame it on racism, it's not within their power to solve it. There are way more people holding different options, no matter holding themselves as racist or not.

WordPress PHP short code to parse markdown

Requirements to include a markdown file from elsewhere emerged when I decide to auto update my blog with github readme page.

Since markdown itself cannot include another markdown file, I come up with a work around to parse the github raw on the air.

The following example requires wp-githuber-md - since I am already using it anyway. Any equivalent will do.

/*====== parse_md shortcode ======*/
function parse_md($atts = [])
    $src = $atts['src'];
    $md = file_get_contents($src);

    if ($md === false)
        $html = "Could not load $src";
        require_once $_SERVER['DOCUMENT_ROOT'] . "/wp-content/plugins/wp-githuber-md/src/Modules/MarkdownParser.php";
        $markdownParser = new Githuber\Module\MarkdownParser;
        $html = $markdownParser->transform($md);

    return $html;
add_shortcode( 'parse_md', 'parse_md' );


[parse_md src="<url>]


往大里说,垄断完大家都没好果子吃。 往小里说,听音乐的方案现在已经由一个软件转化成了多个部分。

  • 听新歌:网易云日推仍然是不错的选择,搭配unblockneteasemusic可以基本覆盖国内流媒体的资源。Spotify备选。
  • 下载 :musictools.exe, spotdl
  • 整理, mp3tag
  • 歌单 :netease-cloudmusic-playlist-exporter
  • 听老歌:foobar2000
  • 安卓 :adb-sync

若是在七年前,上述方案已经简直不要太完美,下载的歌曲配合iTunes便能实现多终端同步,而现在连Apple都转向做流媒体了。 流媒体的到来改变了一切。尝到了流媒体的便捷,再往回走就显得格外困难。 从好处说,流媒体音乐平台极大扩充了音乐来源,保护了音乐版权,激励了音乐人的创作。 往坏处说,垄断的平台使用户丧失了议价的能力,长远来看也会侵蚀音乐人的权益。 垄断平台甚至不需要完全阻断用户的自行方案,他们需要做的只是尽量抬高其他方案的实现门槛。只要他们的方案简单易用并且掌握了大量用户群体,便无需再为用户考虑,躺着数钱即可。 举例来说网易云已经从最开始的自由听歌下载变成了基本不能下载,部分歌曲仅能试听,用来笼络顾客的云盘也基本报废(Edit-20200731 不稳定)。

版权完善方向看,音乐流媒体化是大势所趋。 从道德角度上讲,所有媒体,但凡未曾声明自由传播,都不是免费的。互联网成为盗版的温床正是因为少数人的盗版行为(做种的,上传的,开服务器的,以及许多流媒体平台的早期),配合上法律的漏洞,为普罗大众的盗版行为提供了便捷的借口。 让人感到不安的是,为了保护版权所付出的代价事实上正从用户身上提取。在过去,获得的音乐便是实实在在的文件,如何管理,放在那里听都是用户的选择,也正是这种极大的自由促生了盗版。而现如今,流媒体服务商正以一种廉价的方式提供加密版的文件或数据流以阻止这类自由使用,并同时把越来越多的受众捆绑在自己的平台上,反馈于垄断的加剧。



Email Service!


To create a personal email service

How to

Creating MySQL user

dnf install postfix dovecot dovecot-mysql postfix-mysql mutt
sudo mysqladmin -u root -p create mailserver
sudo mysql -u root -p

Creating the database and tables

/*! Create the MySQL user and grant the new user permissions over the database. */
GRANT SELECT ON mailserver.* TO 'mailuser'@'localhost' IDENTIFIED BY 'mailuserpass';
USE mailserver;

/*! Create a table for the domains that will receive mail */
CREATE TABLE `virtual_domains` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,

/*! Create a table for all of the email addresses and passwords */
CREATE TABLE `virtual_users` (
  `id` int(11) NOT NULL auto_increment,
  `domain_id` int(11) NOT NULL,
  `password` varchar(106) NOT NULL,
  `email` varchar(100) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`),
  FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE

/*! Create a table for the email aliases */
CREATE TABLE `virtual_aliases` (
  `id` int(11) NOT NULL auto_increment,
  `domain_id` int(11) NOT NULL,
  `source` varchar(100) NOT NULL,
  `destination` varchar(100) NOT NULL,
  PRIMARY KEY (`id`),
  FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE

/*! Add the domains */
INSERT INTO `mailserver`.`virtual_domains`
  (`id` ,`name`)
  ('1', '');

/*! Add the users */
INSERT INTO `mailserver`.`virtual_users`
  (`id`, `domain_id`, `password` , `email`)
  ('1', '1', ENCRYPT('password', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), '[email protected]'),
  ('2', '1', ENCRYPT('password', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), '[email protected]'),
  ('101', '1', ENCRYPT('password', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), '[email protected]');

/*! Add the alias */
INSERT INTO `mailserver`.`virtual_aliases`
  (`id`, `domain_id`, `source`, `destination`)
  ('1', '1', '[email protected]', '[email protected]'),
  ('2', '1', '[email protected]', '[email protected]');

note the password can also be generated from python

import crypt
import hashlib
import random
salt = hashlib.sha1(str(random.random()).encode()).hexdigest()[0:16]
print(crypt.crypt("password", "$6$"+salt+"$"))


modified and added files: (see reference for detail)



modified and added files: (see reference for detail)


Post processing

sudo chown -R vmail:dovecot /etc/dovecot
chown -R vmail:dovecot /etc/dovecot
chmod -R o-rwx /etc/dovecot
systemctl restart dovecot
chmod -R o-rwx /etc/postfix
systemctl restart postfix
systemctl enable dovecot
systemctl enable postfix


dnf install mailx
mail [email protected]
tail /var/log/maillog

Client config

465 smtp TLS 587 smtp STARTTLS 993 imap ssl 995 pop3 ssl


  1. Email with Postfix, Dovecot and MariaDB on CentOS 7
  2. Virtual user mail system with Postfix, Dovecot and Roundcube

Heart of Iron 4 (Man the Guns) Germany Fast World Conquest 2nd Try

Basic order

  • Poland, Belgium
  • France, Netherland, UK, Czechoslovakia, Canada
  • US, Australia, New Zealand
  • Switzerland, Italy, South Africa, Romania, Turkey
  • Soviet Union
  • ...

Detailed gameplay (important decisions)

  • 19360319 justify Poland and Belgium (use cancel justification trick to control world tension below 20%)
  • 19360628 MOFO Bill extension
  • 19361225 MOFO Bill extension
  • 19370401 war Poland Belgium
  • 19370607 Poland capitulated
  • 19370728 wait for Maco Polo Incident until world tension increase and Belgium joins Ally, then taking the capital and Belgium capitulated
  • 19370802 France starts the war
  • 19370807 France capitulated
  • 19370815 Vichy France established
  • 19370901 war Netherland
  • 19370907 Netherland capitulated
  • 19370929 cross English Channel
  • 19371217 UK almost capitulated, hold force, 1 division invade Canada
  • 19380111 Czechoslovakia justified
  • 19380119 Czechoslovakia joins Ally
  • 19380126 1 division attack Czechoslovakia and takes capital, US justified, take the final victory point from UK and Ally capitulated, puppet UK established, colony sovereign transferred and everything else annexed
  • 19380406 war US
  • 19380625 US capitulated
  • 19380904 naval invade Australia
  • 19381020 naval invade New Zealand
  • 19381109 Switzerland Italy justified, Ally capitulated, puppet US established, colony sovereign transferred and everything else annexed
  • 19390321 war Italy
  • 19390821 war South Africa
  • 19400210 war Turkey, justify Romania, Ally capitulated (later puppet Romania)
  • 19400411 German East Indies annexed
  • 19400911 France annexed
  • 19400913 Turkey released
  • 19410125 Soviet starts war against Finland, start the war against Soviet, call Romania to join the war
  • 19410310 German Raj annexed
  • 19410709 free attack
  • 19410721 Führer Directive 21 finished
  • 19410810 Sevastopol circled
  • 19411007 Soviet capitulated, puppet Soviet established

Notes for basic gameplay

  • Don't research Navy and Oil, and should be able to keep up with all other researches. Still going to own the strongest navy by annexing France, UK, and US. Still going to have more than enough oil after conquering US.
  • Don't do Rhine land focus because it increases world tension. When the war kicks off it's automatically bypassed. Also, don't set any National focus before 19360319 for the earliest war goal justify.
  • Ally starts war actively if leaving Belgium until Marco Polo incident, which is highly favorable. If world tension is still not high enough, justify Netherland.
  • Use national focus 'Befriend Denmark' for Greenland port access so we can naval invade Canada.
  • 1 division invade Canada, Czechoslovakia, Turkey before Ally capitulated for instant victory.
  • Always remember to justify war goals before Ally capitulated as it cost only 10 or 25 days when at war.
  • Establish Vichy France, UK, US puppet for their navy; Romania for focus (8 bonus military factories); Turkey as buffer country against Soviet; US, Soviet for their manpower (give full territory back before drawing manpower), annex others
  • Draw manpower from German East Indies and France before going to war with Soviet

Notes for invading Soviet

  • Remember to deploy all aircrafts captured before war kicks off.
  • Attack Soviet when it's attacking Finland and its north defence is almost gone. And they still have debuff from Great Purge by then.
  • When invading Soviet leave an army to circle Sevastopol but don't attack. After Moscow falls (so are Leningrad and Stalingrad) the new Soviet capital will be Sevastopol. Block its land access from north and east each with a total of 80 width divisions (1 block width), raiding Black Sea convoy, and the whole Soviet army will be out of supply.
  • Build 40-width tank division for aggressive attack, 20 width infantry division for normal attack, 20-width motorized infantry division for cautious attack (so they don't actively engage and can follow the tank push really fast).
  • 40-width tank divisions are composed of 8 medium tank divisions, 4 SPART divisions, and 6 motorized infantry divisions. 20-width (motorized) infantry divisions are just normal 7+2.
  • The main force composed with 1 army of 24 tank divisions for pushing, 3 armies of 3 tank divisions for micro-management, 1 army of 24 motorized infantry divisions for fast catch up, 5 armies of 24 infantry divisions for holding position and normal attack.
  • Don't try to circle Soviet divisions in large scale until very late, because it's almost impossible when they have a huge amount of backup divisions and will definitely be a supply nightmare. Just do small scale circle that covers 1 to 10 provinces would be good enough. Always build infrastructure when pushing.
  • Don't use a lot of force to invade Soviet from Turkey because the infrastructure is so awful and takes too much to fix. Instead, use a 3 tank divisions army to flank and circle Soviet army just after the main force pushes over Stalingrad.

To continue

In Oct. 1941 China is still resisting Japanese invasion. A navy composed of German, France, UK, US navy should already be overkill for the Japanese navy. Raiding Japanese convoys and their main force will be out of supply. Literally there's no other major which can pose any threat at this point.

To improve

  • This gameplay ensures there is always only 1 main front line so it's easy to micromanage. For ultimate fast conquer multiple frontlines are necessary.
  • Paratroopers are worth considering for even fast early conquer.

Project: create_m3u_from_NeteaseCloudMusic

This project is completed reworked for much better performance and .m3u8 compliance. See release/project-netease-cloudmusic-playlist-exporter/

Netease is working hard to prevent users from listening to local music, especially those VIP exclusive ones. Today (20200531) they even replaced the UWP app with the win32 version in Microsoft Store to force users to accept their new rules: No more VIP music unless you paid, even local ones are not permitted, which is totally ridiculous.

The original UWP app, despite deprecated quite long ago and a little bit ugly, was quite useful on windows tablets as UWP apps are the only choice to play music with the screen turned off.

The project has 2 parts: to find a UWP music player, and exporting the Netease Cloudmusic playlist to it. After some searching, the foobar2000 mobile (not foobar2000) seems to be the only choice.

The exporting process uses Netease Cloudmusic local SQLite database to retrieve the playlist information. Introducing project create_m3u_from_NeteaseCloudMusic: Command Line Tool to Extract ".m3u8" Playlist out of Netease Cloudmusic Library (forked from xyqyear/create_m3u_from_NeteaseCloudMusic)



(wich is equivalent to 'python')

Show help

Exporter.exe -h

Specify playlist to export, or export all

Exporter.exe [-p PLAYLISTNAME]

With this updated version of the command-line tool, an automatic update can be easily done with a '.bat'. Example:

@echo off
REM declare using UTF-8 encoding
chcp 65001
%UserProfile%\AppData\Local\Programs\Python\Python38\python.exe %UserProfile%\repo\create_m3u_from_NeteaseCloudMusic\ --playlist 我喜欢的音乐

The way Foobar2000 mobile works will always ensure the updated '.m3u8' playlist be used.

China Unicom is Stealing User Privacy Including Accounts and Passwords

It’s lucky for me to find this backdoor as there must be some programming error leading to the crash. There is no reason for China Unicom to show up when a user is importing account information of a totally irrelevant service. The only explanation is that it's trying to steal the data. But what's the motive?

ShadowsocksR is a VPN technology that can be used to falsify data streams. China Unicom is probably using this backdoor to capture those who are using ShadowsocksR to get free cellular data.

No matter what its purpose is, this is an act totally ignorant of user privacy, and apparently illegal. The ShadowsocksR configuration it’s been trying to steal contains user account information like account names and passwords. Who knows what other information it might be stealing secretly?

Shame on China Unicom and all those behind it.

Curve Generation Algorithm Development

UCB ARCH 259 Robotic Fabrication

Mark Ma, Yasaman Yavari


The final object is to make something fantastic, while creating a workflow including techniques of 3D scanning, parametric modeling, robotic arm operations, 3D printing and bio-mechanical knowledge.

While breaking down the final object, Yasaman and I found our interest in the parametric modeling part. With instructions from Professor Simon, we began our quest to develop a robot-printing friendly curve generation algorithm. To be robot-printing friendly, the curve generated should have the following features:

  • Artistic (subjective)
  • Reasonably structured (objective)
  • As continuous as possible so that saves the trouble of reconnecting during printing (objective)


Base shape

With the conclusion that we’re to use elastic canvas for basic form-finding, the first step of our modeling would be simulating this process. Several opinions are available:

  • Use finite element method to find the exact shape of the canvas under loading
  • Use Kangaroo to simulate the physical process
  • Use minimal surface

The minimal surface method is dropped due to the fact that we are to use form-finding in reality. The FEA method, despite exact and promising, does not go well with the rest of the project with its model format. Considering that the modeling precision would not be a big issue in this step, Yasaman and I decided to use Kangaroo for base shape simulation.

The drawback of Kangaroo is that we can hardly define an isotropic elastic material. The Quadrilateral Mesh, despite simple and straightforward, promises the same modulus only in the orthogonal direction of the mesh UV basis.

Through careful modeling, I add another restriction at 45° and 135° of the UV basis, making it closer to an isotropic material. Considering the exact model are to be found out using real form-finding and 3D-scanner, the remaining error is neglected.

20200501 Base Shape
20200501 Base Shape

Structural reasonableness

Considering the problem to be print on the basic form, several ideas of curve generation have been proposed. One plan is to adopt optimized principle stress lines. The advantage is obvious, as such a structure would be very reasonable under loading. However, principal stress lines turned out hard to be adopted. The continuity of the principle stress line does not guarantee the well-distribution of these lines, which often leaves large holes in structure generated. Due to the high sensitiveness to shape and load, the principal stress lines are hard to manipulate too. Consequently, we decided to start from the curve generation itself.

Curve generation

Step 1. Curve generated according to force distribution

One way of curve generation is to divide and lengthen parts of a continuous curve, while keeping the curve away from intersecting with itself, which defines all the goals we need to implement this idea with Kangaroo:

  • Lengthen curve sections
  • Prevent curve from intersecting with itself

To adapt the generated curves responsive to structural behavior, it's natural to densify the area with large stress, which gives the third goal:

  • Curve distribution responsive to stress distribution

With these goals the curves are successfully generated, meeting all our objective goals. Further development should focus on the subjective part, aka the artistic effects.

20200501 Step 1
20200501 Step 1

Step 2. Curve generated freely

To gain more control of the curve generation, some restrictions have to be dropped. Now take a look back at the initial three goals, if we neglect the curve distribution requirement, we can achieve something looks very alike Zaha’s project.

20200501 Step 2
20200501 Step 2

Recall that Zaha’s project uses a manually defined base curve to approximate initial stress distribution, we now certainly have a better solution: to use the curve generated in 1st step as the base shape for 2nd step, which gives us the following result.

20200501 Step 12
20200501 Step 12

Step 3. Combination

There is an infinite number of curves we can generate by tweaking with all the parameters, and an even larger infinite number of combinations with different layer position, tube thickness, color, etc. For a quick example, this is what it will look like if we combine Step 1+2 as a thicker base layer and Step 2 as a thinner decoration layer.

20200501 Step 3
20200501 Step 3


The curve generation is a complex workflow not fully automated, as lots of attention needs to be paid to calibrate all the parameters in order to get the best shape. All generated curves have the potential to become the final project, with a combination of each other and further improvement based on printing practice.

Due to the virus situation nowadays, it’s becoming harder for our project to be actually constructed. I hope all these quests into curve generation can be preserved, developed, and applied in future practice.


  1. Zaha Hadid Design - Thallus for for White in the City Animation - YouTube

  2. Curve growth - differential growth (Where to Start?) - Grasshopper - McNeel Forum

Coco (2017)

A story about a boy trying to prove himself a citizen with unconditional civil rights, and a distant relative (his great-great-grandpa) trying to get a visitor visa through him.

Family ties ARE important. For sure. Gracias, señor Trump.

Evidence of your employment and/or your family ties may be sufficient to show the purpose of your trip and your intent to return to your home country.

Visitor Visa

Export MATLAB LiveScript into Viewable PDF

MATLAB LiveScript can be exported into pdf but the function is often broken. Sometimes figures are too large to stay in page frame, or it doesn't show figures at all.

To bypass this broken feature one possible way around is to save as HTML, and edit CSS to make sure things look normal before finally printing it into PDF.

Some useful CSS property to pay attention to:

    max-hight: none; !important
    max-width: 100%;


Convert encrypted ncm file to original music file

Forked from magic-akari/ncmc

Replace comments value with the original 163 key so songs can be recognized correctly by cloudmusic clients.

License: MIT

Dynamo vs. Grasshopper

I finally got my hands on Dynamo trying to model a parametric triangular sphere, which I have done several weeks earlier in Grasshopper. Convinced by Zhekai Li that Dynamo would perform better since it has advantage over complex modeling situation, I started from scratch to learn Dynamo. And 2 days later, eureka!


So let's come back to the topic: how does it feel to model something in Dynamo comparing with Grasshopper?

Los Angeles Trip on Christmas

I finally decided to participate in the trip after 1 minutes' 'careful' consideration. It would be such a pity if I didn't take a tour around LA when I am living so close to it - only 381.9 miles away, especially with the Airbnb already booked and trip planned ahead by someone else. After all what could go wrong? Everthing


夷歌阿豪切大?偶德尼涩偶fə'lə窝里哼nou个尼泽古古, nou’ciang么挖机撒落列wə
... you never really forget them. It just takes a while for your memory to come back to you - Spirited Away (2001)


n2n is a solution for Virtual LAN.

With VLAN many things can be quite easy, e.g. SMB sharing across NAT.

工E十周年 贺电





Spirited Away (2001)

Now go, and don't look back.

Spirited Away (2001) Faceless. Exiled by myself.

7 years.

It's time.

General parametric design of a steel-glubam hybrid space truss

Ma, K., and Xiao, Y. “General Parametric Design of a Steel-Glubam Hybrid Space Truss.” In Modern Engineered Bamboo Structures: Proceedings of the Third International Conference on Modern Bamboo Structures (ICBS 2018), June 25-27, 2018, Beijing, China, 1st ed., 223–29. CRC Press, 2019.

K. Ma

Zhejiang Univ.-Univ. of Illinois at Urbana Champaign Institute, Jiaxing, Zhejiang, China

Y. Xiao

Zhejiang Univ.-Univ. of Illinois at Urbana Champaign Institute, Jiaxing, Zhejiang, China

Nanjing Tech University, Nanjing, Jiangsu, China

Department of Civil Engineering, University of Southern California, Los Angeles, CA, USA

ABSTRACT: This paper introduces a parametric design method for a hybrid truss system composed of glued laminated bamboo (glubam) and steel. Experiments on determining material’s physical and mechanical parameters were carried out first, on basis of which design stages from modeling, analysis, optimization to manufacturing are all rendered possible through parametric ways by defining corresponding parameters within one single platform - Grasshopper. By maximizing automation during the process, efficiency and extensibility are taken into consideration for possibly further, larger, and more complex design.

Good Lab

A structural lab that is clean is not a good lab. -- Khalid M. Mosalam on CE 249, Sept. 6, 2019

edit 20220801:

The ZJU Haining campus recruited a new Civ Lab engineer recently, who is dedicated to make the Civ lab 'as clean and beautiful as a museum'. He once proposed that wood cutting should be done outside of the Lab to minimize the noise and ash, and I had to call the Dean in to revert this policy.

With his help everyting is now put in order far away from its supposed working location, just we can not find things when we need, and the lab engineer has no idea too.

How ironically!

Force Loading Earlier Version Extension in Visual Studio 2019

Encountered 'This extension is already installed to all applicable products.' error when trying to install 'NewGrasshopperTemplate.vsix' to vs2019. Open vsix as zip, update all '.json' files by replacing [15.0,16.0\)` with `[15.0,17.0\) And it worked.

Project: Large Waste Transfer Station

20190628 Large Waste Transfer Station 20190628 Large Waste Transfer Station

20190811 Large Waste Transfer Station 20200811 Large Waste Transfer Station

20190815 Large Waste Transfer Station 20200815 Large Waste Transfer Station


Directed by Prof. Yan Xiao.

Designed by Mark Ma.

Non-commercial project for research and demo purpose.

wm density Crash Rescue

device: Mi MIX 2S system: MIUI 10

Try and fail

My device crashed after trying to modify window density.

wm density 120

Screen went dark, adb shell reports error.

.\adb shell wm density reset

Tried force reboot, not working, and adb shell no longer worked due to permission. Device auto reboot into recovery.

Tried everything from Google and nothing works.

Tried adb command when restarting but encountered error.

.\adb shell wm density reset
Security exception: Must hold permission android.permission.WRITE_SECURE_SETTINGS


This reminds me of a way to circumvent device password lock, which I accidentally bumped into 2 weeks ago when modifying status bar icon.

Simply rename/remove


Then reboot, you'll find yourself home screen immediately!!! Do anything you like to fix the resolution.

Project: Concrete Dragon

About the project

Concrete is something not often linked to boat, let alone dragon boat. Traditional concept of concrete based building material is embedded deeply not only in common folks but also in Civil Engineering students.

Concrete, usually Portland cement concrete (for its visual resemblance to Portland stone), is a composite material composed of fine and coarse aggregate bonded together with a fluid cement (cement paste) that hardens over time

Concrete - Wikipedia

Still, concrete is just a material, and material evolves as scientific progress advances. New material such as FRP rebars show even better performance than traditional steel rebars. Moreover, as its Chinese name indicated, concrete is just 'some sort of ash mixed and hardens', expanding its concept to a even higher dimension. Comparing to traditional boat building material, concrete has its own pros and cons.


  • Stain proof (v.s. steel)
  • Flexible shape (v.s. timber)
  • Economical (v.s. steel and timber)


  • Heavier than water and timber
  • Brittle
  • Low tensile strength

The whole project is aimed at exploiting the advantages of concrete while fixing its problems, expanding our knowledge of concrete through engineering practice.

Prototype 1.x - The First FRP Concrete Dragon Boat


A new type of boat construction method is proposed firstly by Prof. Yan Xiao. The basic idea is to use a self-hardening FRP cloth material as both concrete model and structural part that provides tensile strength.

20190615 Prototype 1.x Cross Section
20190615 Prototype 1.x Cross Section


FRP Clothes

This is some material recently become popular for its ability of free shaping and fast hardening. Most common scenario of usage is replacement of medical bondage and plaster, or electrical wire joint protection. The mechanism is really simple as it's just piece of FRP soaked into glue. Exposition to air solidify the glue in several minutes, providing the structure with some strength.

Things become interesting when several layers of such kind of material are glued together. As FRP clothes is extremely strong in tensile direction, even glue can sustain the relatively less strong shearing force, guaranteeing high bending and shearing strength.

Plastic Hull

A plastic hull is needed for this model, primarily for the shape control of the self-hardening FRP clothes. To achieve better dynamic performance, hull is modeled to be smooth and continuous - NURBS interposition of key points. Therefore, 3D-printing technology is adopted for precise realization of the model.

20190406 3D Printing
20190406 3D Printing
20190223 Modal Boat Hull
20190223 Modal Boat Hull
20190317 Modal Boat Covered by FRP with Kaihang Zhang
20190317 Modal Boat Covered by FRP with Kaihang Zhang


ECC concrete is a new kind of concrete which includes PVA fiber to increase its tensile strength and crack resistance. Ingredients are listed as below:

Quartz Sand 20-401.1
Silica Fume0.3
Mineral Powder0.1
Quartz Sand 3250.1
PVA Fiber
Water Reduce Agents0.10%
Early Strength Agents0.10%

Next Stage

Prototype 1.x focuses itself on boat construction. A boat floating on the water marked success of the first stage. On that occasion, however, path splits for two different prototypes though.

Prototype 2.x stays small and is optimized for wireless remote control. A concrete dragon boat (model) competition is later held based on this. Prototype 3.x is develped with optimization for man-powered sailing in a much larger scale - a real concrete dragon boat.

Prototype 2.x - ICDBC 2019


Fast, stable, swift steering

To make it fast, the boat has to be speed boat alike, narrow, and light. The concrete layer needs to be as thin as possible. For sure, boat surface still needs to be smooth and continuous.

To make it stable and swift steering, the boat has to be not that narrow in width, motors parallel to each other and as far away as each other as possible.

Power system

Duo RH-380 motors, 1500mAh Li-ion battery

Should gave adopted stronger motors.



CentOS7, php7.2, MySQL5.3, Nginx, WordPress Vultr Dallas

See Concrete Dragon Online.


Should have set limitations on motor power.


Should have provided ai version.

Should have made it clear that theme color can be switched.

Should have designed certificate templates.

Next stage

Should have adopted Arduino.

20190606 ICDBC Boat of My Team
20190606 ICDBC Boat of My Team
20190606 ICDBC Jury Committee with Boats
20190606 ICDBC Jury Committee with Boats
20190606 ICDBC Prof. Yan Xiao
20190606 ICDBC Prof. Yan Xiao
20190606 ICDBC Everyone
20190606 ICDBC Everyone

Prototype 3.x - The Great Dragon Boat


Strong, stable, light

The large boat is very different from the small boat as construction method can not be inherited directly. It is too slow for the hull to be 3d-printed out. Instead, EPS foam slices cut by CO2 laser are glued (or tied) up to form the basic model of the boat. A FRP clothes layer is then put on the foam, then concrete with FRP bars inside.

20190526 Laser Cut Plastic Foam
20190526 Laser Cut Plastic Foam

To make the boat strong, the boat is modeled even more smooth, to the extent that FRP rebars can be put inside the concrete from head to tail without cut or connect. Such smooth shape without any edge can be regarded as a 2-d arch, making the most of the compressive strength of the concrete. To make the boat stable, the boat should have a lower gravity center.

20190615 Prototype 2.x Cross Section
20190615 Prototype 2.x Cross Section
20190531 Great Dragon Boat Foam and Dr. Dade Lai
20190531 Great Dragon Boat Foam and Dr. Dade Lai
20190601 Great Dragon Boat Covered by Concrete
20190601 Great Dragon Boat Covered by Concrete
20190604 Great Dragon Boat under Painting
20190604 Great Dragon Boat under Painting
20190606 Great Dragon Boat
20190606 Great Dragon Boat

Next stage

  • Should have the whole boat hull made by solid EPS form.
  • Should have adopted sprayed concrete technique.
  • Should have used more PVA.
  • Should have used more FRP fiber clothes.



Yan Xiao 肖岩

Boat Designer, Engineer, Manufacturer, Website Programmer and Designer

Ke Ma 马克


Ke Ma 马克, Dade Lai 赖大德, Zhiwei He 贺智伟

Also thanks for help by

Anqi Tan 谭安琪, Yiqi Feng 冯亦奇, Kaihang Zhang 张开航, Zhekai Li 李哲楷, Mengjun Wang 王梦君, Guoli Wang 汪郭立, Yang Zhou 周洋, Shangchun Jiang 江上春, Cristoforo Demartino, Zicheng Bao 包梓成

Decoration by

Jiahui Liang 梁嘉惠, Ke Ma 马克, Sicheng Zhou 周思成, Anqi Tan 谭安琪, Qingyun Liu 柳青云

Concrete Recipe

Bo Shan 单波, Dade Lai 赖大德

Logistic Support by

Sicheng Zhou 周思成

Competition Rule Maker

Yan Xiao 肖岩, Ke Ma 马克, Yiqi Feng 冯亦奇, Anqi Tan 谭安琪, Kaihang Zhang 张开航

Activity Organizer

Hang Wu 吴行, Ke Ma 马克, Binbin Li 李宾宾, Yanlong Xie 谢焱龙, Sichen Zhou 周思成, Tao Li 李涛, Jiahui Liang 梁嘉惠, Zhiwei He 贺智伟, Dade Lai 赖大德, Haixiang Zhu 朱海翔, Yi Zhang 张旖, Chenchen Ye 叶晨晨, Qian Yu 余倩, Jinyan Yu 俞静琰, Fengqing Jiang 江凤清 and other volunteers from ZJUI

Special Thanks for

Logistic Support

Jiyao Guo 郭霁瑶, Zhaijin Jia 贾翟菁, Qingbing Xie 谢庆兵

Technical Support

Tianyi Han 韩天屹, Si Li 李斯


Yue Feng 冯越, Hanyin Shao 邵寒吟



Some Thoughts from the Great Dragon Project

Stress does not get the better of me, but sense of responsibility does. I am accustomed to be alone, still, sense of loneliness and isolation horrified me.

People like me do not climb to leading position due to their ability to lead people, but as a result of responsibility and judgement. Team members may not believe the leader's judgement, but they do rely on it - as long as the leader shoulder all the responsibility, they are happy with it. Such ultra unstable system will collapse as soon as any mistake happens, especially those out of control, either by the leader himself, or by some team member - doesn't matter - team members will soon lose their interest or hope to fix the problem. And mistake is almost definitely to come around.

Problem originates from the responsibility system. Students who I lead, most come to the project with just out of curiosity, or even unwillingness. They have nothing beneficial from me, nor threatened by any power from me. The only reason they follow my order, is out of trust, that I could make sure that the problem be solved at the lowest cost of their time and work.

So the 'solution' is clear now. Under such condition, best solution is to assign tasks and orders as simple as possible to everyone and let them believe that this is the best way that they could get away from this, after they finish their part. Sadly, machine is always stronger than people in terms of obeying orders.

First rule of leadership: PICK the right team member.


Shot on my way back to office after dinner, in Zhejiang University International Campus, Haining, Zhejinag, China. The flying object was flying with a tail of fixed length, generally from South to North, to the West of the campus. Video shot with my phone, stabilized by Ae and is speeded up to 10 times.

Given the almost horizental track, and the fact that there's no smoke behind, there's high possibility that the object was moving at high altitude.

No news though.

Project: Waste Transfer Station

20190324 Waste Transfer Station 1.0.1 Day 1 20190324 Waste Transfer Station, by Y. Xiao, K. Ma

202001030925 Waste Transfer Station 202001030925 Waste Transfer Station, Photo by S.C. Zhou


Directed by Prof. Yan Xiao.

Designed by Mark Ma.

Non-commercial project for research and demo purpose.