mirror of
https://github.com/CHN-beta/nixos.git
synced 2024-10-22 20:58:45 +08:00
Compare commits
10 Commits
66e3d95ac4
...
e441395c36
Author | SHA1 | Date | |
---|---|---|---|
e441395c36 | |||
35856d9293 | |||
36190b5e93 | |||
14c86412a1 | |||
8d3e516c62 | |||
e3fe00a53d | |||
feb5a5b952 | |||
59c3b98223 | |||
14fdf5a1f6 | |||
1a7137fda7 |
@ -41,7 +41,7 @@ inputs:
|
||||
initrd.sshd.enable = true;
|
||||
nixpkgs.march = "silvermont";
|
||||
nix.substituters = [ "https://nix-store.chn.moe?priority=100" ];
|
||||
networking = { hostname = "nas"; networkd = {}; };
|
||||
networking.networkd = {};
|
||||
};
|
||||
hardware = { cpus = [ "intel" ]; gpu.type = "intel"; };
|
||||
services =
|
||||
|
@ -53,7 +53,6 @@ inputs:
|
||||
modules.modprobeConfig =
|
||||
[ "options iwlwifi power_save=0" "options iwlmvm power_scheme=1" "options iwlwifi uapsd_disable=1" ];
|
||||
};
|
||||
networking.hostname = "pc";
|
||||
sysctl.laptop-mode = 5;
|
||||
gui.enable = true;
|
||||
};
|
||||
|
@ -18,7 +18,7 @@ inputs:
|
||||
swap = [ "/nix/swap/swap" ];
|
||||
rollingRootfs = {};
|
||||
};
|
||||
networking = { hostname = "pi3b"; networkd = {}; };
|
||||
networking.networkd = {};
|
||||
nixpkgs.arch = "aarch64";
|
||||
kernel.variant = "nixos";
|
||||
};
|
||||
|
@ -1,50 +0,0 @@
|
||||
inputs:
|
||||
{
|
||||
config =
|
||||
{
|
||||
nixos =
|
||||
{
|
||||
system =
|
||||
{
|
||||
fileSystems =
|
||||
{
|
||||
mount =
|
||||
{
|
||||
vfat."/dev/disk/by-uuid/7A60-4232" = "/boot";
|
||||
btrfs."/dev/mapper/root1" = { "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
||||
};
|
||||
swap = [ "/dev/mapper/swap" ];
|
||||
rollingRootfs = {};
|
||||
};
|
||||
nixpkgs.march = "cascadelake";
|
||||
kernel.variant = "xanmod-lts";
|
||||
networking.hostname = "srv1-node0";
|
||||
gui.enable = true;
|
||||
};
|
||||
packages.vasp = null;
|
||||
hardware.cpus = [ "intel" ];
|
||||
services =
|
||||
{
|
||||
snapper.enable = true;
|
||||
sshd = {};
|
||||
xray.client.enable = true;
|
||||
smartd.enable = true;
|
||||
beesd.instances.root = { device = "/"; hashTableSizeMB = 4096; threads = 4; };
|
||||
wireguard =
|
||||
{
|
||||
enable = true;
|
||||
peers = [ "vps6" ];
|
||||
publicKey = "l1gFSDCeBxyf/BipXNvoEvVvLqPgdil84nmr5q6+EEw=";
|
||||
wireguardIp = "192.168.83.3";
|
||||
};
|
||||
slurm =
|
||||
{
|
||||
enable = true;
|
||||
cpu = { cores = 16; threads = 2; mpiThreads = 2; openmpThreads = 4; };
|
||||
memoryMB = 90112;
|
||||
};
|
||||
};
|
||||
user.users = [ "chn" ];
|
||||
};
|
||||
};
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
inputs:
|
||||
{
|
||||
config =
|
||||
{
|
||||
nixos =
|
||||
{
|
||||
system =
|
||||
{
|
||||
fileSystems =
|
||||
{
|
||||
mount =
|
||||
{
|
||||
vfat."/dev/disk/by-uuid/7A60-4232" = "/boot";
|
||||
btrfs."/dev/mapper/root1" = { "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
||||
};
|
||||
swap = [ "/dev/mapper/swap" ];
|
||||
rollingRootfs = {};
|
||||
};
|
||||
nixpkgs.march = "broadwell";
|
||||
kernel.variant = "xanmod-lts";
|
||||
networking.hostname = "srv1-node3";
|
||||
gui.enable = true;
|
||||
};
|
||||
packages.vasp = null;
|
||||
hardware.cpus = [ "intel" ];
|
||||
services =
|
||||
{
|
||||
snapper.enable = true;
|
||||
sshd = {};
|
||||
xray.client.enable = true;
|
||||
smartd.enable = true;
|
||||
beesd.instances.root = { device = "/"; hashTableSizeMB = 4096; threads = 4; };
|
||||
wireguard =
|
||||
{
|
||||
enable = true;
|
||||
peers = [ "vps6" ];
|
||||
publicKey = "l1gFSDCeBxyf/BipXNvoEvVvLqPgdil84nmr5q6+EEw=";
|
||||
wireguardIp = "192.168.83.3";
|
||||
};
|
||||
slurm =
|
||||
{
|
||||
enable = true;
|
||||
cpu = { cores = 16; threads = 2; mpiThreads = 2; openmpThreads = 4; };
|
||||
memoryMB = 90112;
|
||||
};
|
||||
};
|
||||
user.users = [ "chn" ];
|
||||
};
|
||||
};
|
||||
}
|
29
devices/srv1/default.nix
Normal file
29
devices/srv1/default.nix
Normal file
@ -0,0 +1,29 @@
|
||||
inputs:
|
||||
{
|
||||
config =
|
||||
{
|
||||
nixos =
|
||||
{
|
||||
system =
|
||||
{
|
||||
fileSystems = { swap = [ "/dev/mapper/swap" ]; rollingRootfs = {}; };
|
||||
kernel.variant = "xanmod-lts";
|
||||
gui.enable = true;
|
||||
};
|
||||
hardware.cpus = [ "intel" ];
|
||||
services =
|
||||
{
|
||||
snapper.enable = true;
|
||||
sshd = {};
|
||||
smartd.enable = true;
|
||||
slurm =
|
||||
{
|
||||
enable = true;
|
||||
cpu = { cores = 16; threads = 2; mpiThreads = 2; openmpThreads = 4; };
|
||||
memoryMB = 90112;
|
||||
};
|
||||
};
|
||||
user.users = [ "chn" ];
|
||||
};
|
||||
};
|
||||
}
|
31
devices/srv1/node0/default.nix
Normal file
31
devices/srv1/node0/default.nix
Normal file
@ -0,0 +1,31 @@
|
||||
inputs:
|
||||
{
|
||||
config =
|
||||
{
|
||||
nixos =
|
||||
{
|
||||
system =
|
||||
{
|
||||
fileSystems.mount =
|
||||
{
|
||||
vfat."/dev/disk/by-uuid/7A60-4232" = "/boot";
|
||||
btrfs."/dev/mapper/root1" = { "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
||||
};
|
||||
nixpkgs.march = "cascadelake";
|
||||
};
|
||||
packages.vasp = null;
|
||||
services =
|
||||
{
|
||||
xray.client.enable = true;
|
||||
beesd.instances.root = { device = "/"; hashTableSizeMB = 4096; threads = 4; };
|
||||
wireguard =
|
||||
{
|
||||
enable = true;
|
||||
peers = [ "vps6" ];
|
||||
publicKey = "l1gFSDCeBxyf/BipXNvoEvVvLqPgdil84nmr5q6+EEw=";
|
||||
wireguardIp = "192.168.83.3";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
31
devices/srv1/node3/default.nix
Normal file
31
devices/srv1/node3/default.nix
Normal file
@ -0,0 +1,31 @@
|
||||
inputs:
|
||||
{
|
||||
config =
|
||||
{
|
||||
nixos =
|
||||
{
|
||||
system =
|
||||
{
|
||||
fileSystems.mount =
|
||||
{
|
||||
vfat."/dev/disk/by-uuid/7A60-4232" = "/boot";
|
||||
btrfs."/dev/mapper/root1" = { "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
||||
};
|
||||
nixpkgs.march = "broadwell";
|
||||
};
|
||||
packages.vasp = null;
|
||||
services =
|
||||
{
|
||||
xray.client.enable = true;
|
||||
beesd.instances.root = { device = "/"; hashTableSizeMB = 4096; threads = 4; };
|
||||
wireguard =
|
||||
{
|
||||
enable = true;
|
||||
peers = [ "vps6" ];
|
||||
publicKey = "l1gFSDCeBxyf/BipXNvoEvVvLqPgdil84nmr5q6+EEw=";
|
||||
wireguardIp = "192.168.83.3";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -26,7 +26,6 @@ inputs:
|
||||
nixpkgs.march = "skylake";
|
||||
nix = { substituters = [ "https://nix-store.chn.moe?priority=100" ]; githubToken.enable = true; };
|
||||
kernel = { variant = "xanmod-lts"; patches = [ "surface" "hibernate-progress" ]; };
|
||||
networking.hostname = "surface";
|
||||
gui.enable = true;
|
||||
};
|
||||
hardware = { cpus = [ "intel" ]; gpu.type = "intel"; };
|
||||
|
@ -29,7 +29,7 @@ inputs:
|
||||
nixpkgs.march = "znver2";
|
||||
nix.substituters = [ "https://nix-store.chn.moe?priority=100" ];
|
||||
initrd.sshd.enable = true;
|
||||
networking = { hostname = "vps4"; networkd = {}; };
|
||||
networking.networkd = {};
|
||||
kernel.variant = "xanmod-latest";
|
||||
nix-ld = null;
|
||||
binfmt = null;
|
||||
|
@ -29,7 +29,7 @@ inputs:
|
||||
nixpkgs.march = "sandybridge";
|
||||
nix.substituters = [ "https://nix-store.chn.moe?priority=100" ];
|
||||
initrd.sshd.enable = true;
|
||||
networking = { hostname = "vps6"; networkd = {}; };
|
||||
networking.networkd = {};
|
||||
# do not use cachyos kernel, beesd + cachyos kernel + heavy io = system freeze, not sure why
|
||||
};
|
||||
services =
|
||||
|
@ -29,7 +29,7 @@ inputs:
|
||||
nixpkgs.march = "znver2";
|
||||
nix.substituters = [ "https://nix-store.chn.moe?priority=100" ];
|
||||
initrd.sshd.enable = true;
|
||||
networking = { hostname = "vps7"; networkd = {}; };
|
||||
networking.networkd = {};
|
||||
kernel.variant = "xanmod-lts";
|
||||
};
|
||||
services =
|
||||
|
@ -48,7 +48,6 @@ inputs:
|
||||
};
|
||||
};
|
||||
gui = { enable = true; preferred = false; autoStart = true; };
|
||||
networking.hostname = "xmupc1";
|
||||
nix.remote.slave.enable = true;
|
||||
};
|
||||
hardware = { cpus = [ "amd" ]; gpu.type = "nvidia"; };
|
||||
|
@ -41,7 +41,6 @@ inputs:
|
||||
};
|
||||
};
|
||||
gui = { enable = true; preferred = false; autoStart = true; };
|
||||
networking.hostname = "xmupc2";
|
||||
nix =
|
||||
{
|
||||
marches =
|
||||
|
150
flake.nix
150
flake.nix
@ -76,144 +76,14 @@
|
||||
# nixos-wallpaper = { url = "git+https://git.chn.moe/chn/nixos-wallpaper.git"; flake = false; };
|
||||
};
|
||||
|
||||
outputs = inputs:
|
||||
let
|
||||
localLib = import ./lib.nix inputs.nixpkgs.lib;
|
||||
devices = builtins.filter (dir: (builtins.readDir ./devices/${dir})."default.nix" or null == "regular" )
|
||||
(builtins.attrNames (builtins.readDir ./devices));
|
||||
in
|
||||
{
|
||||
packages.x86_64-linux = rec
|
||||
{
|
||||
pkgs = (import inputs.nixpkgs
|
||||
{
|
||||
system = "x86_64-linux";
|
||||
config.allowUnfree = true;
|
||||
overlays = [ inputs.self.overlays.default ];
|
||||
});
|
||||
default = inputs.nixpkgs.legacyPackages.x86_64-linux.writeText "systems"
|
||||
(builtins.concatStringsSep "\n" (builtins.map
|
||||
(system: builtins.toString inputs.self.outputs.nixosConfigurations.${system}.config.system.build.toplevel)
|
||||
devices));
|
||||
hpcstat =
|
||||
let
|
||||
openssh = (pkgs.pkgsStatic.openssh.override { withLdns = false; etcDir = null; }).overrideAttrs
|
||||
(prev: { doCheck = false; patches = prev.patches ++ [ ./packages/hpcstat/openssh.patch ];});
|
||||
duc = pkgs.pkgsStatic.duc.override { enableCairo = false; cairo = null; pango = null; };
|
||||
in pkgs.pkgsStatic.localPackages.hpcstat.override
|
||||
{ inherit openssh duc; standalone = true; version = inputs.self.rev or "dirty"; };
|
||||
ufo =
|
||||
let
|
||||
range-v3 = pkgs.pkgsStatic.range-v3.overrideAttrs (prev:
|
||||
{
|
||||
cmakeFlags = prev.cmakeFlags or []
|
||||
++ [ "-DRANGE_V3_DOCS=OFF" "-DRANGE_V3_TESTS=OFF" "-DRANGE_V3_EXAMPLES=OFF" ];
|
||||
doCheck = false;
|
||||
});
|
||||
tbb = pkgs.pkgsStatic.tbb_2021_11.overrideAttrs (prev: { cmakeFlags = prev.cmakeFlags or [] ++
|
||||
[ "-DTBB_TEST=OFF" ]; });
|
||||
biu = pkgs.pkgsStatic.localPackages.biu.override { inherit range-v3; };
|
||||
matplotplusplus = pkgs.pkgsStatic.localPackages.matplotplusplus.override { libtiff = null; };
|
||||
in pkgs.pkgsStatic.localPackages.ufo.override { inherit biu tbb matplotplusplus; };
|
||||
chn-bsub = pkgs.pkgsStatic.localPackages.chn-bsub;
|
||||
blog = pkgs.callPackage ./blog { inherit (inputs) hextra; };
|
||||
}
|
||||
// (builtins.listToAttrs (builtins.map
|
||||
(system:
|
||||
{
|
||||
name = system;
|
||||
value = inputs.self.outputs.nixosConfigurations.${system}.config.system.build.toplevel;
|
||||
})
|
||||
devices)
|
||||
);
|
||||
nixosConfigurations =
|
||||
(
|
||||
(builtins.listToAttrs (builtins.map
|
||||
(system:
|
||||
{
|
||||
name = system;
|
||||
value = inputs.nixpkgs.lib.nixosSystem
|
||||
{
|
||||
system = "x86_64-linux";
|
||||
specialArgs = { topInputs = inputs; inherit localLib; };
|
||||
modules = localLib.mkModules
|
||||
[
|
||||
(moduleInputs: { config.nixpkgs.overlays = [(prev: final:
|
||||
# replace pkgs with final to avoid infinite recursion
|
||||
{ localPackages = import ./packages (moduleInputs // { pkgs = final; }); })]; })
|
||||
./modules
|
||||
./devices/${system}
|
||||
];
|
||||
};
|
||||
})
|
||||
devices))
|
||||
// {
|
||||
pi3b = inputs.nixpkgs.lib.nixosSystem
|
||||
{
|
||||
system = "aarch64-linux";
|
||||
specialArgs = { topInputs = inputs; inherit localLib; };
|
||||
modules = localLib.mkModules
|
||||
[
|
||||
(moduleInputs: { config.nixpkgs.overlays = [(prev: final:
|
||||
# replace pkgs with final to avoid infinite recursion
|
||||
{ localPackages = import ./packages (moduleInputs // { pkgs = final; }); })]; })
|
||||
./modules
|
||||
./devices/pi3b
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
overlays.default = final: prev:
|
||||
{ localPackages = (import ./packages { inherit (inputs) lib; pkgs = final; topInputs = inputs; }); };
|
||||
config = { archive = false; branch = "production"; };
|
||||
devShells.x86_64-linux = let inherit (inputs.self.nixosConfigurations.pc) pkgs; in
|
||||
{
|
||||
biu = pkgs.mkShell.override { stdenv = pkgs.clang18Stdenv; }
|
||||
{
|
||||
inputsFrom = [ pkgs.localPackages.biu ];
|
||||
packages = [ pkgs.clang-tools_18 ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
hpcstat = pkgs.mkShell.override { stdenv = pkgs.clang18Stdenv; }
|
||||
{
|
||||
inputsFrom = [ (pkgs.localPackages.hpcstat.override { version = null; }) ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
sbatch-tui = pkgs.mkShell.override { stdenv = pkgs.clang18Stdenv; }
|
||||
{
|
||||
inputsFrom = [ pkgs.localPackages.sbatch-tui ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
ufo = pkgs.mkShell.override { stdenv = pkgs.clang18Stdenv; }
|
||||
{
|
||||
inputsFrom = [ pkgs.localPackages.ufo ];
|
||||
packages = [ pkgs.clang-tools_18 ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
chn-bsub = pkgs.mkShell
|
||||
{
|
||||
inputsFrom = [ pkgs.localPackages.chn-bsub ];
|
||||
packages = [ pkgs.clang-tools_18 ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
winjob =
|
||||
let inherit (pkgs) clang-tools_18; in let inherit (inputs.self.packages.x86_64-w64-mingw32) pkgs winjob;
|
||||
in pkgs.mkShell.override { stdenv = pkgs.gcc14Stdenv; }
|
||||
{
|
||||
inputsFrom = [ winjob ];
|
||||
packages = [ clang-tools_18 ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
};
|
||||
src = let inherit (inputs.self.packages.x86_64-linux) pkgs; in
|
||||
{
|
||||
nixos-wallpaper = pkgs.fetchgit
|
||||
{
|
||||
url = "https://git.chn.moe/chn/nixos-wallpaper.git";
|
||||
rev = "1ad78b20b21c9f4f7ba5f4c897f74276763317eb";
|
||||
sha256 = "0faahbzsr44bjmwr6508wi5hg59dfb57fzh5x6jh7zwmv4pzhqlb";
|
||||
fetchLFS = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
outputs = inputs: let localLib = import ./flake/lib.nix inputs.nixpkgs.lib; in
|
||||
{
|
||||
packages.x86_64-linux = import ./flake/packages.nix { inherit inputs localLib; };
|
||||
nixosConfigurations = import ./flake/nixos.nix { inherit inputs localLib; };
|
||||
overlays.default = final: prev:
|
||||
{ localPackages = (import ./packages { inherit localLib; pkgs = final; topInputs = inputs; }); };
|
||||
config = { archive = false; branch = "production"; };
|
||||
devShells.x86_64-linux = import ./flake/dev.nix { inherit inputs; };
|
||||
src = import ./flake/src.nix { inherit inputs; };
|
||||
};
|
||||
}
|
||||
|
39
flake/dev.nix
Normal file
39
flake/dev.nix
Normal file
@ -0,0 +1,39 @@
|
||||
{ inputs }: let inherit (inputs.self.nixosConfigurations.pc) pkgs; in
|
||||
{
|
||||
biu = pkgs.mkShell.override { stdenv = pkgs.clang18Stdenv; }
|
||||
{
|
||||
inputsFrom = [ pkgs.localPackages.biu ];
|
||||
packages = [ pkgs.clang-tools_18 ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
hpcstat = pkgs.mkShell.override { stdenv = pkgs.clang18Stdenv; }
|
||||
{
|
||||
inputsFrom = [ (pkgs.localPackages.hpcstat.override { version = null; }) ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
sbatch-tui = pkgs.mkShell.override { stdenv = pkgs.clang18Stdenv; }
|
||||
{
|
||||
inputsFrom = [ pkgs.localPackages.sbatch-tui ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
ufo = pkgs.mkShell.override { stdenv = pkgs.clang18Stdenv; }
|
||||
{
|
||||
inputsFrom = [ pkgs.localPackages.ufo ];
|
||||
packages = [ pkgs.clang-tools_18 ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
chn-bsub = pkgs.mkShell
|
||||
{
|
||||
inputsFrom = [ pkgs.localPackages.chn-bsub ];
|
||||
packages = [ pkgs.clang-tools_18 ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
winjob =
|
||||
let inherit (pkgs) clang-tools_18; in let inherit (inputs.self.packages.x86_64-w64-mingw32) pkgs winjob;
|
||||
in pkgs.mkShell.override { stdenv = pkgs.gcc14Stdenv; }
|
||||
{
|
||||
inputsFrom = [ winjob ];
|
||||
packages = [ clang-tools_18 ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
}
|
51
flake/nixos.nix
Normal file
51
flake/nixos.nix
Normal file
@ -0,0 +1,51 @@
|
||||
{ inputs, localLib }:
|
||||
builtins.listToAttrs
|
||||
(
|
||||
(builtins.map
|
||||
(system:
|
||||
{
|
||||
name = system;
|
||||
value = inputs.nixpkgs.lib.nixosSystem
|
||||
{
|
||||
system = let arch.pi3b = "aarch64-linux"; in arch.${system} or "x86_64-linux";
|
||||
specialArgs = { topInputs = inputs; inherit localLib; };
|
||||
modules = localLib.mkModules
|
||||
[
|
||||
{
|
||||
config =
|
||||
{
|
||||
nixpkgs.overlays = [ inputs.self.overlays.default ];
|
||||
nixos.system.networking.hostname = system;
|
||||
};
|
||||
}
|
||||
../modules
|
||||
../devices/${system}
|
||||
];
|
||||
};
|
||||
})
|
||||
[ "nas" "pc" "pi3b" "surface" "vps4" "vps6" "vps7" "xmupc1" "xmupc2" ])
|
||||
++ (builtins.map
|
||||
(node:
|
||||
{
|
||||
name = "srv1-${node}";
|
||||
value = inputs.nixpkgs.lib.nixosSystem
|
||||
{
|
||||
system = "x86_64-linux";
|
||||
specialArgs = { topInputs = inputs; inherit localLib; };
|
||||
modules = localLib.mkModules
|
||||
[
|
||||
{
|
||||
config =
|
||||
{
|
||||
nixpkgs.overlays = [ inputs.self.overlays.default ];
|
||||
nixos.system.cluster = { clusterName = "srv1"; nodeName = node; };
|
||||
};
|
||||
}
|
||||
../modules
|
||||
../devices/srv1
|
||||
../devices/srv1/${node}
|
||||
];
|
||||
};
|
||||
})
|
||||
[ "node0" "node3" ])
|
||||
)
|
21
flake/packages.nix
Normal file
21
flake/packages.nix
Normal file
@ -0,0 +1,21 @@
|
||||
{ inputs, localLib }: rec
|
||||
{
|
||||
pkgs = (import inputs.nixpkgs
|
||||
{
|
||||
system = "x86_64-linux";
|
||||
config.allowUnfree = true;
|
||||
overlays = [ inputs.self.overlays.default ];
|
||||
});
|
||||
hpcstat =
|
||||
let
|
||||
openssh = (pkgs.pkgsStatic.openssh.override { withLdns = false; etcDir = null; }).overrideAttrs
|
||||
(prev: { doCheck = false; patches = prev.patches ++ [ ../packages/hpcstat/openssh.patch ];});
|
||||
duc = pkgs.pkgsStatic.duc.override { enableCairo = false; cairo = null; pango = null; };
|
||||
in pkgs.pkgsStatic.localPackages.hpcstat.override
|
||||
{ inherit openssh duc; standalone = true; version = inputs.self.rev or "dirty"; };
|
||||
chn-bsub = pkgs.pkgsStatic.localPackages.chn-bsub;
|
||||
blog = pkgs.callPackage ../blog { inherit (inputs) hextra; };
|
||||
}
|
||||
// (builtins.listToAttrs (builtins.map
|
||||
(system: { inherit (system) name; value = system.value.config.system.build.toplevel; })
|
||||
(localLib.attrsToList inputs.self.outputs.nixosConfigurations)))
|
10
flake/src.nix
Normal file
10
flake/src.nix
Normal file
@ -0,0 +1,10 @@
|
||||
{ inputs }: let inherit (inputs.self.packages.x86_64-linux) pkgs; in
|
||||
{
|
||||
nixos-wallpaper = pkgs.fetchgit
|
||||
{
|
||||
url = "https://git.chn.moe/chn/nixos-wallpaper.git";
|
||||
rev = "1ad78b20b21c9f4f7ba5f4c897f74276763317eb";
|
||||
sha256 = "0faahbzsr44bjmwr6508wi5hg59dfb57fzh5x6jh7zwmv4pzhqlb";
|
||||
fetchLFS = true;
|
||||
};
|
||||
}
|
@ -16,7 +16,7 @@ inputs:
|
||||
# system management
|
||||
# TODO: module should add yubikey-touch-detector into path
|
||||
gparted wayland-utils clinfo glxinfo vulkan-tools dracut yubikey-touch-detector btrfs-assistant snapper-gui
|
||||
kdePackages.qtstyleplugin-kvantum ventoy-full cpu-x inputs.pkgs."pkgs-23.11".etcher wl-mirror
|
||||
kdePackages.qtstyleplugin-kvantum ventoy-full cpu-x wl-mirror # inputs.pkgs."pkgs-23.11".etcher
|
||||
(
|
||||
writeShellScriptBin "xclip"
|
||||
''
|
||||
|
21
modules/system/cluster.nix
Normal file
21
modules/system/cluster.nix
Normal file
@ -0,0 +1,21 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.system.cluster = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule { options =
|
||||
{
|
||||
clusterName = mkOption { type = types.nonEmptyStr; };
|
||||
nodeName = mkOption { type = types.nonEmptyStr; };
|
||||
nodeType = mkOption { type = types.enum [ "master" "worker" ]; default = "worker"; };
|
||||
};});
|
||||
default = null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.system) cluster; in inputs.lib.mkIf (cluster != null)
|
||||
{
|
||||
nixos.system.networking.hostname = "${cluster.clusterName}-${cluster.nodeName}";
|
||||
# 作为从机时,home-manager 需要被禁用
|
||||
systemd.services = inputs.lib.mkIf (cluster.nodeType == "worker") (builtins.listToAttrs (builtins.map
|
||||
(user: { name = "home-manager-${user}"; value.enable = false; })
|
||||
inputs.config.nixos.user.users));
|
||||
};
|
||||
}
|
@ -5,28 +5,26 @@ inputs:
|
||||
enable = mkOption { type = types.bool; default = true; };
|
||||
keyPathPrefix = mkOption { type = types.str; default = "/nix/persistent"; };
|
||||
};
|
||||
config =
|
||||
let
|
||||
inherit (inputs.lib) mkIf;
|
||||
inherit (inputs.config.nixos.system) sops;
|
||||
in mkIf sops.enable
|
||||
config = let inherit (inputs.config.nixos.system) sops; in inputs.lib.mkIf sops.enable
|
||||
{
|
||||
sops =
|
||||
{
|
||||
sops =
|
||||
{
|
||||
defaultSopsFile =
|
||||
let deviceDir = "${inputs.topInputs.self}/devices/${inputs.config.nixos.system.networking.hostname}";
|
||||
in mkIf
|
||||
(
|
||||
builtins.pathExists "${deviceDir}/secrets.yaml"
|
||||
|| builtins.pathExists "${deviceDir}/secrets/default.yaml"
|
||||
)
|
||||
(
|
||||
if builtins.pathExists "${deviceDir}/secrets.yaml" then "${deviceDir}/secrets.yaml"
|
||||
else "${deviceDir}/secrets/default.yaml"
|
||||
);
|
||||
# sops start before impermanence, so we need to use the absolute path
|
||||
age.sshKeyPaths = [ "${sops.keyPathPrefix}/etc/ssh/ssh_host_ed25519_key" ];
|
||||
gnupg.sshKeyPaths = [ "${sops.keyPathPrefix}/etc/ssh/ssh_host_rsa_key" ];
|
||||
};
|
||||
defaultSopsFile =
|
||||
let deviceDir =
|
||||
if (inputs.config.nixos.system.cluster == null) then
|
||||
"${inputs.topInputs.self}/devices/${inputs.config.nixos.system.networking.hostname}"
|
||||
else
|
||||
"${inputs.topInputs.self}/devices/${inputs.config.nixos.system.cluster.clusterName}"
|
||||
+ "/${inputs.config.nixos.system.cluster.nodeName}";
|
||||
in inputs.lib.mkMerge
|
||||
[
|
||||
(inputs.lib.mkIf (builtins.pathExists "${deviceDir}/secrets.yaml") "${deviceDir}/secrets.yaml")
|
||||
(inputs.lib.mkIf (builtins.pathExists "${deviceDir}/secrets/default.yaml")
|
||||
"${deviceDir}/secrets/default.yaml")
|
||||
];
|
||||
# sops start before impermanence, so we need to use the absolute path
|
||||
age.sshKeyPaths = [ "${sops.keyPathPrefix}/etc/ssh/ssh_host_ed25519_key" ];
|
||||
gnupg.sshKeyPaths = [ "${sops.keyPathPrefix}/etc/ssh/ssh_host_rsa_key" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ inputs:
|
||||
};
|
||||
home-manager.users.chn =
|
||||
{
|
||||
imports = [ "${inputs.topInputs.impermanence}/home-manager.nix" ];
|
||||
config =
|
||||
{
|
||||
programs =
|
||||
@ -81,39 +82,65 @@ inputs:
|
||||
))
|
||||
)
|
||||
];
|
||||
persistence =
|
||||
{
|
||||
"/nix/persistent/home/chn" =
|
||||
{
|
||||
directories =
|
||||
[
|
||||
# common things
|
||||
"bin" "Desktop" "Documents" "Downloads" "Music" "Pictures" "repo" "share" "Public" "Videos"
|
||||
".config" ".local/share"
|
||||
# xmuvpn
|
||||
".ecdata"
|
||||
# firefox
|
||||
".mozilla/firefox/default"
|
||||
# ssh
|
||||
".ssh"
|
||||
# steam
|
||||
".steam" # ".local/share/Steam"
|
||||
# vscode
|
||||
".vscode" # ".config/Code" ".config/grammarly-languageserver"
|
||||
# zotero
|
||||
".zotero" "Zotero"
|
||||
];
|
||||
allowOther = true;
|
||||
};
|
||||
"/nix/rootfs/current/home/chn".allowOther = true;
|
||||
};
|
||||
};
|
||||
pam.yubico.authorizedYubiKeys.ids = [ "cccccbgrhnub" ];
|
||||
};
|
||||
};
|
||||
environment.persistence =
|
||||
let inherit (inputs.config.nixos.system) impermanence; in inputs.lib.mkIf impermanence.enable
|
||||
{
|
||||
# TODO: make copy or soft link of files
|
||||
"${impermanence.persistence}".users.chn =
|
||||
{
|
||||
directories = builtins.map
|
||||
(dir: { directory = dir.dir or dir; user = "chn"; group = "chn"; mode = dir.mode or "0755"; })
|
||||
[
|
||||
# common things
|
||||
"bin" "Desktop" "Documents" "Downloads" "Music" "Pictures" "repo" "share" "Public" "Videos"
|
||||
".config" ".local/share"
|
||||
# # gnome
|
||||
# { dir = ".config/dconf"; mode = "0700"; } ".config/gtk-2.0" ".config/gtk-3.0" ".config/gtk-4.0"
|
||||
# ".config/libaccounts-glib"
|
||||
# # android
|
||||
# { dir = ".android"; mode = "0750";}
|
||||
# xmuvpn
|
||||
".ecdata"
|
||||
# firefox
|
||||
{ dir = ".mozilla/firefox/default"; mode = "0700"; }
|
||||
# ssh
|
||||
{ dir = ".ssh"; mode = "0700"; }
|
||||
# steam
|
||||
".steam" # ".local/share/Steam"
|
||||
# vscode
|
||||
".vscode" # ".config/Code" ".config/grammarly-languageserver"
|
||||
# zotero
|
||||
".zotero" "Zotero"
|
||||
# environment.persistence =
|
||||
# let inherit (inputs.config.nixos.system) impermanence; in inputs.lib.mkIf impermanence.enable
|
||||
# {
|
||||
# # TODO: make copy or soft link of files
|
||||
# "${impermanence.persistence}".users.chn =
|
||||
# {
|
||||
# directories = builtins.map
|
||||
# (dir: { directory = dir.dir or dir; user = "chn"; group = "chn"; mode = dir.mode or "0755"; })
|
||||
# [
|
||||
# # common things
|
||||
# "bin" "Desktop" "Documents" "Downloads" "Music" "Pictures" "repo" "share" "Public" "Videos"
|
||||
# ".config" ".local/share"
|
||||
# # # gnome
|
||||
# # { dir = ".config/dconf"; mode = "0700"; } ".config/gtk-2.0" ".config/gtk-3.0" ".config/gtk-4.0"
|
||||
# # ".config/libaccounts-glib"
|
||||
# # # android
|
||||
# # { dir = ".android"; mode = "0750";}
|
||||
# # xmuvpn
|
||||
# ".ecdata"
|
||||
# # firefox
|
||||
# { dir = ".mozilla/firefox/default"; mode = "0700"; }
|
||||
# # ssh
|
||||
# { dir = ".ssh"; mode = "0700"; }
|
||||
# # steam
|
||||
# ".steam" # ".local/share/Steam"
|
||||
# # vscode
|
||||
# ".vscode" # ".config/Code" ".config/grammarly-languageserver"
|
||||
# # zotero
|
||||
# ".zotero" "Zotero"
|
||||
# 百度网盘
|
||||
# ".config/BaiduPCS-Go"
|
||||
# # bitwarden
|
||||
@ -196,7 +223,7 @@ inputs:
|
||||
# ".local/share/waydroid"
|
||||
# # zsh
|
||||
# ".local/share/zsh"
|
||||
];
|
||||
# ];
|
||||
# TODO: create file if not exist
|
||||
# files = builtins.map
|
||||
# (file: { inherit file; parentDirectory = { user = "chn"; group = "chn"; mode = "0755"; }; })
|
||||
@ -212,7 +239,5 @@ inputs:
|
||||
# # age TODO: use sops to storage
|
||||
# ".config/sops/age/keys.txt"
|
||||
# ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -2,74 +2,72 @@ inputs:
|
||||
{
|
||||
config = inputs.lib.mkIf inputs.config.nixos.system.gui.enable
|
||||
{
|
||||
home-manager.users.chn.config.home.file =
|
||||
let
|
||||
programs =
|
||||
{
|
||||
nheko = rec
|
||||
home-manager.users.chn.config.home =
|
||||
{
|
||||
file =
|
||||
let
|
||||
programs =
|
||||
{
|
||||
fileName = "nheko.desktop";
|
||||
path = "${inputs.pkgs.nheko}/share/applications/${fileName}";
|
||||
nheko = rec
|
||||
{
|
||||
fileName = "nheko.desktop";
|
||||
path = "${inputs.pkgs.nheko}/share/applications/${fileName}";
|
||||
};
|
||||
kclockd = rec
|
||||
{
|
||||
fileName = "org.kde.kclockd-autostart.desktop";
|
||||
path = "${inputs.pkgs.kdePackages.kdeGear.kclock}/etc/xdg/autostart/${fileName}";
|
||||
};
|
||||
yakuake = rec
|
||||
{
|
||||
fileName = "org.kde.yakuake.desktop";
|
||||
path = "${inputs.pkgs.yakuake}/share/applications/${fileName}";
|
||||
};
|
||||
telegram = rec
|
||||
{
|
||||
fileName = "org.telegram.desktop.desktop";
|
||||
path = inputs.pkgs.writeText fileName (builtins.replaceStrings
|
||||
[ "Exec=telegram-desktop -- %u" ] [ "Exec=telegram-desktop -autostart" ]
|
||||
(builtins.readFile "${inputs.pkgs.telegram-desktop}/share/applications/${fileName}"));
|
||||
};
|
||||
element = rec
|
||||
{
|
||||
fileName = "element-desktop.desktop";
|
||||
path = inputs.pkgs.writeText fileName (builtins.replaceStrings
|
||||
[ "Exec=element-desktop %u" ] [ "Exec=element-desktop --hidden" ]
|
||||
(builtins.readFile "${inputs.pkgs.element-desktop.desktopItem}/share/applications/${fileName}"));
|
||||
};
|
||||
kmail = rec
|
||||
{
|
||||
fileName = "org.kde.kmail2.desktop";
|
||||
path = "${inputs.pkgs.kmail}/share/applications/${fileName}";
|
||||
};
|
||||
discord = rec
|
||||
{
|
||||
fileName = "discord.desktop";
|
||||
path = inputs.pkgs.writeText fileName (builtins.replaceStrings
|
||||
[ "Exec=Discord" ] [ "Exec=Discord --start-minimized" ]
|
||||
(builtins.readFile "${inputs.pkgs.discord.desktopItem}/share/applications/${fileName}"));
|
||||
};
|
||||
crow-translate = rec
|
||||
{
|
||||
fileName = "io.crow_translate.CrowTranslate.desktop";
|
||||
path = "${inputs.pkgs.crow-translate}/share/applications/${fileName}";
|
||||
};
|
||||
};
|
||||
kclockd = rec
|
||||
devices =
|
||||
{
|
||||
fileName = "org.kde.kclockd-autostart.desktop";
|
||||
path = "${inputs.pkgs.kdePackages.kdeGear.kclock}/etc/xdg/autostart/${fileName}";
|
||||
pc = [ "nheko" "kclockd" "yakuake" "telegram" "element" "kmail" "discord" "crow-translate" ];
|
||||
surface = [ "kclockd" "yakuake" "telegram" "element" "crow-translate" ];
|
||||
};
|
||||
yakuake = rec
|
||||
{
|
||||
fileName = "org.kde.yakuake.desktop";
|
||||
path = "${inputs.pkgs.yakuake}/share/applications/${fileName}";
|
||||
};
|
||||
telegram = rec
|
||||
{
|
||||
fileName = "org.telegram.desktop.desktop";
|
||||
path = inputs.pkgs.writeText fileName (builtins.replaceStrings
|
||||
[ "Exec=telegram-desktop -- %u" ] [ "Exec=telegram-desktop -autostart" ]
|
||||
(builtins.readFile "${inputs.pkgs.telegram-desktop}/share/applications/${fileName}"));
|
||||
};
|
||||
element = rec
|
||||
{
|
||||
fileName = "element-desktop.desktop";
|
||||
path = inputs.pkgs.writeText fileName (builtins.replaceStrings
|
||||
[ "Exec=element-desktop %u" ] [ "Exec=element-desktop --hidden" ]
|
||||
(builtins.readFile "${inputs.pkgs.element-desktop.desktopItem}/share/applications/${fileName}"));
|
||||
};
|
||||
kmail = rec
|
||||
{
|
||||
fileName = "org.kde.kmail2.desktop";
|
||||
path = "${inputs.pkgs.kmail}/share/applications/${fileName}";
|
||||
};
|
||||
discord = rec
|
||||
{
|
||||
fileName = "discord.desktop";
|
||||
path = inputs.pkgs.writeText fileName (builtins.replaceStrings
|
||||
[ "Exec=Discord" ] [ "Exec=Discord --start-minimized" ]
|
||||
(builtins.readFile "${inputs.pkgs.discord.desktopItem}/share/applications/${fileName}"));
|
||||
};
|
||||
crow-translate = rec
|
||||
{
|
||||
fileName = "io.crow_translate.CrowTranslate.desktop";
|
||||
path = "${inputs.pkgs.crow-translate}/share/applications/${fileName}";
|
||||
};
|
||||
};
|
||||
devices =
|
||||
{
|
||||
pc = [ "nheko" "kclockd" "yakuake" "telegram" "element" "kmail" "discord" "crow-translate" ];
|
||||
surface = [ "kclockd" "yakuake" "telegram" "element" "crow-translate" ];
|
||||
};
|
||||
in builtins.listToAttrs (builtins.map
|
||||
in builtins.listToAttrs (builtins.map
|
||||
(file:
|
||||
{
|
||||
name = ".config/autostart/${programs.${file}.fileName}";
|
||||
value.source = programs.${file}.path;
|
||||
})
|
||||
(devices.${inputs.config.nixos.system.networking.hostname} or []));
|
||||
environment.persistence =
|
||||
let impermanence = inputs.config.nixos.system.impermanence;
|
||||
in inputs.lib.mkIf impermanence.enable
|
||||
{
|
||||
"${impermanence.root}".users.chn.directories = [ ".config/autostart" ];
|
||||
};
|
||||
persistence."/nix/rootfs/current/home/chn".directories = [ ".config/autostart" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -63,12 +63,13 @@ inputs:
|
||||
"Terminal Features".BlinkingCursorEnabled.value = true;
|
||||
};
|
||||
};
|
||||
home.file.".local/share/konsole/Breeze.colorscheme".text = builtins.replaceStrings
|
||||
[ "Opacity=1" ] [ "Opacity=0.9\nBlur=true" ]
|
||||
(builtins.readFile "${inputs.pkgs.konsole}/share/konsole/Breeze.colorscheme");
|
||||
home =
|
||||
{
|
||||
file.".local/share/konsole/Breeze.colorscheme".text = builtins.replaceStrings
|
||||
[ "Opacity=1" ] [ "Opacity=0.9\nBlur=true" ]
|
||||
(builtins.readFile "${inputs.pkgs.konsole}/share/konsole/Breeze.colorscheme");
|
||||
persistence."/nix/rootfs/current/home/chn".directories = [ ".local/share/konsole" ".local/share/yakuake" ];
|
||||
};
|
||||
};
|
||||
environment.persistence =
|
||||
let impermanence = inputs.config.nixos.system.impermanence; in inputs.lib.mkIf impermanence.enable
|
||||
{ "${impermanence.root}".users.chn.directories = [ ".local/share/konsole" ".local/share/yakuake" ]; };
|
||||
};
|
||||
}
|
||||
|
@ -84,9 +84,10 @@ inputs:
|
||||
home-manager.users = builtins.listToAttrs (builtins.map
|
||||
(name: { inherit name; value.imports = user.sharedModules; })
|
||||
user.users);
|
||||
environment.persistence."${inputs.config.nixos.system.impermanence.persistence}".directories = builtins.map
|
||||
(user: { directory = "/home/${user}"; inherit user; group = user; mode = "0700"; })
|
||||
(builtins.filter (user: user != "chn") user.users);
|
||||
environment.persistence."${inputs.config.nixos.system.impermanence.persistence}".directories =
|
||||
inputs.lib.mkIf (inputs.config.nixos.system.cluster.nodeType or null != "worker") (builtins.map
|
||||
(user: { directory = "/home/${user}"; inherit user; group = user; mode = "0700"; })
|
||||
(builtins.filter (user: user != "chn") user.users));
|
||||
}
|
||||
# set hashedPassword if it exist in secrets
|
||||
(
|
||||
|
@ -2,7 +2,6 @@
|
||||
# include <fmt/core.h>
|
||||
# include <fmt/ranges.h>
|
||||
# include <fmt/std.h>
|
||||
# include <fmt/ostream.h>
|
||||
# include <fmt/chrono.h>
|
||||
# include <fmt/xchar.h>
|
||||
# include <nameof.hpp>
|
||||
|
@ -7,6 +7,16 @@
|
||||
|
||||
namespace biu
|
||||
{
|
||||
// This should be defined in header
|
||||
inline Atomic<Logger::LoggerConfigType_> Logger::LoggerConfig_ = Logger::LoggerConfigType_
|
||||
{
|
||||
std::experimental::make_observer(&std::clog), nullptr,
|
||||
# ifdef NDEBUG
|
||||
Logger::Level::Info
|
||||
# else
|
||||
Logger::Level::Debug
|
||||
# endif
|
||||
};
|
||||
template <typename T> Logger::ObjectMonitor<T>::ObjectMonitor()
|
||||
: CreateTime_{std::chrono::steady_clock::now()}
|
||||
{
|
||||
|
@ -3,15 +3,6 @@
|
||||
|
||||
namespace biu
|
||||
{
|
||||
Atomic<Logger::LoggerConfigType_> Logger::LoggerConfig_ = Logger::LoggerConfigType_
|
||||
{
|
||||
std::experimental::make_observer(&std::clog), nullptr,
|
||||
# ifdef NDEBUG
|
||||
Logger::Level::Info
|
||||
# else
|
||||
Logger::Level::Debug
|
||||
# endif
|
||||
};
|
||||
void Logger::init(std::experimental::observer_ptr<std::ostream> stream, Level level)
|
||||
{ LoggerConfig_ = LoggerConfigType_{stream, nullptr, level}; }
|
||||
void Logger::init(std::shared_ptr<std::ostream> stream, Level level)
|
||||
|
@ -28,6 +28,4 @@ message("List of compile features: ${CMAKE_CXX_COMPILE_FEATURES}")
|
||||
|
||||
include(CTest)
|
||||
add_test(NAME fold COMMAND ufo fold ${PROJECT_SOURCE_DIR}/test/fold/config.yaml)
|
||||
add_test(NAME fold-compare COMMAND ${CMAKE_COMMAND} -E compare_files fold-output.yaml
|
||||
${PROJECT_SOURCE_DIR}/test/fold/output.yaml)
|
||||
set_tests_properties(fold-compare PROPERTIES DEPENDS fold)
|
||||
|
||||
|
@ -9,6 +9,7 @@ namespace ufo
|
||||
// 也就是说, 正格子与倒格子的转置相乘, 得到单位矩阵.
|
||||
|
||||
using namespace biu::literals;
|
||||
using namespace biu::stream_operators;
|
||||
|
||||
void fold(std::string config_file);
|
||||
void unfold(std::string config_file);
|
||||
|
@ -4,7 +4,8 @@ void ufo::fold(std::string config_file)
|
||||
{
|
||||
struct Input
|
||||
{
|
||||
Eigen::Matrix<int, 3, 3> SuperCellTransformation;
|
||||
Eigen::Matrix3d SuperCellDeformation;
|
||||
Eigen::Vector3i SuperCellMultiplier;
|
||||
std::vector<Eigen::Vector3d> Qpoints;
|
||||
std::optional<std::string> OutputFile;
|
||||
};
|
||||
@ -15,7 +16,7 @@ void ufo::fold(std::string config_file)
|
||||
auto fold = []
|
||||
(
|
||||
Eigen::Vector3d qpoint_in_reciprocal_primitive_cell_by_reciprocal_primitive_cell,
|
||||
Eigen::Matrix<int, 3, 3> super_cell_transformation
|
||||
Eigen::Matrix3d super_cell_transformation
|
||||
) -> Eigen::Vector3d
|
||||
{
|
||||
/*
|
||||
@ -35,8 +36,7 @@ void ufo::fold(std::string config_file)
|
||||
*/
|
||||
auto qpoint_by_reciprocal_super_cell =
|
||||
(
|
||||
super_cell_transformation.cast<double>()
|
||||
* qpoint_in_reciprocal_primitive_cell_by_reciprocal_primitive_cell
|
||||
super_cell_transformation * qpoint_in_reciprocal_primitive_cell_by_reciprocal_primitive_cell
|
||||
).eval();
|
||||
/*
|
||||
到目前为止,我们还没有移动过 q 点的坐标。现在,我们将它移动整数个 ReciprocalSuperCell,直到它落在超胞的倒格子中。
|
||||
@ -49,7 +49,7 @@ void ufo::fold(std::string config_file)
|
||||
output.Qpoints = input.Qpoints
|
||||
| ranges::views::transform([&](auto& qpoint)
|
||||
{
|
||||
return fold(qpoint, input.SuperCellTransformation);
|
||||
return fold(qpoint, input.SuperCellDeformation * input.SuperCellMultiplier.cast<double>().asDiagonal());
|
||||
})
|
||||
| ranges::to_vector;
|
||||
|
||||
|
@ -11,9 +11,14 @@ void ufo::plot_band(std::string config_file)
|
||||
// 内层表示一个路径上的 q 点,外层表示不同的路径
|
||||
// 单位为倒格矢
|
||||
std::vector<std::vector<Eigen::Vector3d>> Qpoints;
|
||||
struct { std::size_t X, Y; } Resolution;
|
||||
// 插值时使用的分辨率(不影响画出来图片的分辨率和横纵比)
|
||||
std::array<std::size_t, 2> InterpolationResolution;
|
||||
// 画图区域的y轴和x轴的比例。如果不指定,则由matplot++自动调整(通常调整为正方形,即 1)
|
||||
std::optional<double> AspectRatio;
|
||||
// 整张图片的分辨率
|
||||
std::optional<std::array<std::size_t, 2>> PictureResolution;
|
||||
// 画图的频率范围
|
||||
struct { double Min, Max; } FrequencyRange;
|
||||
std::array<double, 2> FrequencyRange;
|
||||
// 搜索 q 点时的阈值,单位为埃^-1
|
||||
std::optional<double> ThresholdWhenSearchingQpoints;
|
||||
// 是否要在 y 轴上作一些标记
|
||||
@ -81,8 +86,8 @@ void ufo::plot_band(std::string config_file)
|
||||
// 所有 q 点的数据(需要用到它的频率和权重)
|
||||
const std::vector<UnfoldOutput::QpointDataType>& qpoints,
|
||||
// 用于插值的分辨率和范围
|
||||
const std::pair<unsigned, unsigned>& resolution,
|
||||
const std::pair<double, double>& frequency_range,
|
||||
const std::array<std::size_t, 2>& resolution,
|
||||
const std::array<double, 2>& frequency_range,
|
||||
// 路径的总长度
|
||||
double total_distance
|
||||
)
|
||||
@ -96,7 +101,7 @@ void ufo::plot_band(std::string config_file)
|
||||
bool continuous,
|
||||
// 第一个点占的比例
|
||||
double ratio,
|
||||
unsigned resolution, std::pair<double, double> frequency_range
|
||||
std::size_t resolution, std::array<double, 2> frequency_range
|
||||
) -> std::vector<double>
|
||||
{
|
||||
// 混合得到的频率和权重
|
||||
@ -105,7 +110,7 @@ void ufo::plot_band(std::string config_file)
|
||||
if (continuous)
|
||||
{
|
||||
assert(qpoints[a].ModeData.size() == qpoints[b].ModeData.size());
|
||||
for (unsigned i = 0; i < qpoints[a].ModeData.size(); i++)
|
||||
for (std::size_t i = 0; i < qpoints[a].ModeData.size(); i++)
|
||||
{
|
||||
frequency.push_back
|
||||
(qpoints[a].ModeData[i].Frequency * ratio + qpoints[b].ModeData[i].Frequency * (1 - ratio));
|
||||
@ -115,44 +120,44 @@ void ufo::plot_band(std::string config_file)
|
||||
// 如果是不连续路径,将每个模式的权重乘以比例,最后相加
|
||||
else
|
||||
{
|
||||
for (unsigned i = 0; i < qpoints[a].ModeData.size(); i++)
|
||||
for (std::size_t i = 0; i < qpoints[a].ModeData.size(); i++)
|
||||
{
|
||||
frequency.push_back(qpoints[a].ModeData[i].Frequency);
|
||||
weight.push_back(qpoints[a].ModeData[i].Weight * ratio);
|
||||
}
|
||||
for (unsigned i = 0; i < qpoints[b].ModeData.size(); i++)
|
||||
for (std::size_t i = 0; i < qpoints[b].ModeData.size(); i++)
|
||||
{
|
||||
frequency.push_back(qpoints[b].ModeData[i].Frequency);
|
||||
weight.push_back(qpoints[b].ModeData[i].Weight * (1 - ratio));
|
||||
}
|
||||
}
|
||||
std::vector<double> result(resolution);
|
||||
for (unsigned i = 0; i < frequency.size(); i++)
|
||||
for (std::size_t i = 0; i < frequency.size(); i++)
|
||||
{
|
||||
int index = (frequency[i] - frequency_range.first) / (frequency_range.second - frequency_range.first)
|
||||
std::ptrdiff_t index = (frequency[i] - frequency_range[0]) / (frequency_range[1] - frequency_range[0])
|
||||
* resolution;
|
||||
if (index >= 0 && index < static_cast<int>(resolution)) result[index] += weight[i];
|
||||
if (index >= 0 && index < static_cast<std::ptrdiff_t>(resolution)) result[index] += weight[i];
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
std::vector<std::vector<double>> values;
|
||||
for (unsigned i = 0; i < resolution.first; i++)
|
||||
for (std::size_t i = 0; i < resolution[0]; i++)
|
||||
{
|
||||
auto current_distance = total_distance * i / resolution.first;
|
||||
auto current_distance = total_distance * i / resolution[0];
|
||||
auto it = path.lower_bound(current_distance);
|
||||
if (it == path.begin()) values.push_back(blend
|
||||
(it->second, it->second, true, 1, resolution.second, frequency_range));
|
||||
(it->second, it->second, true, 1, resolution[1], frequency_range));
|
||||
else if (it == path.end()) values.push_back(blend
|
||||
(
|
||||
std::prev(it)->second, std::prev(it)->second, true, 1,
|
||||
resolution.second, frequency_range
|
||||
resolution[1], frequency_range
|
||||
));
|
||||
else values.push_back(blend
|
||||
(
|
||||
std::prev(it)->second, it->second, !path_begin.contains(it->second),
|
||||
(it->first - current_distance) / (it->first - std::prev(it)->first),
|
||||
resolution.second, frequency_range
|
||||
resolution[1], frequency_range
|
||||
));
|
||||
}
|
||||
return values;
|
||||
@ -164,7 +169,9 @@ void ufo::plot_band(std::string config_file)
|
||||
const std::vector<std::vector<double>>& values,
|
||||
const std::string& filename,
|
||||
const std::vector<double>& x_ticks, const std::vector<double>& y_ticks,
|
||||
const std::vector<std::string>& y_ticklabels
|
||||
const std::vector<std::string>& y_ticklabels,
|
||||
const std::optional<double>& aspect_ratio,
|
||||
const std::optional<std::array<std::size_t, 2>>& resolution
|
||||
)
|
||||
{
|
||||
std::vector<std::vector<double>>
|
||||
@ -172,8 +179,8 @@ void ufo::plot_band(std::string config_file)
|
||||
g(values[0].size(), std::vector<double>(values.size(), 0)),
|
||||
b(values[0].size(), std::vector<double>(values.size(), 0)),
|
||||
a(values[0].size(), std::vector<double>(values.size(), 0));
|
||||
for (unsigned i = 0; i < values[0].size(); i++)
|
||||
for (unsigned j = 0; j < values.size(); j++)
|
||||
for (std::size_t i = 0; i < values[0].size(); i++)
|
||||
for (std::size_t j = 0; j < values.size(); j++)
|
||||
{
|
||||
auto v = values[j][i];
|
||||
if (v < 0.05) v = 0;
|
||||
@ -196,6 +203,16 @@ void ufo::plot_band(std::string config_file)
|
||||
ax->y_axis().tick_values(y_ticks);
|
||||
ax->y_axis().tick_length(1);
|
||||
ax->y_axis().ticklabels(y_ticklabels);
|
||||
if (aspect_ratio)
|
||||
{
|
||||
ax->axes_aspect_ratio_auto(false);
|
||||
ax->axes_aspect_ratio(*aspect_ratio);
|
||||
}
|
||||
if (resolution)
|
||||
{
|
||||
f->width((*resolution)[0]);
|
||||
f->height((*resolution)[1]);
|
||||
}
|
||||
f->save(filename, "png");
|
||||
};
|
||||
|
||||
@ -241,30 +258,34 @@ void ufo::plot_band(std::string config_file)
|
||||
// 计算画图的数据
|
||||
auto values = calculate_values
|
||||
(
|
||||
path, path_begin, unfolded_data.QpointData, {input.Resolution.X, input.Resolution.Y},
|
||||
{input.FrequencyRange.Min, input.FrequencyRange.Max}, total_distance
|
||||
path, path_begin, unfolded_data.QpointData, input.InterpolationResolution,
|
||||
input.FrequencyRange, total_distance
|
||||
);
|
||||
auto x_ticks = x_ticks_index | ranges::views::transform([&](auto i)
|
||||
{ return path.nth(i)->first / total_distance * input.Resolution.X; }) | ranges::to<std::vector>;
|
||||
{ return path.nth(i)->first / total_distance * input.InterpolationResolution[0]; }) | ranges::to<std::vector>;
|
||||
auto y_ticks = input.YTicks.value_or(std::vector<std::pair<double, std::string>>{})
|
||||
| biu::toLvalue | ranges::views::keys
|
||||
| ranges::views::transform([&](auto i)
|
||||
{
|
||||
return (i - input.FrequencyRange.Min) / (input.FrequencyRange.Max - input.FrequencyRange.Min)
|
||||
* input.Resolution.Y;
|
||||
return (i - input.FrequencyRange[0]) / (input.FrequencyRange[1] - input.FrequencyRange[0])
|
||||
* input.InterpolationResolution[1];
|
||||
})
|
||||
| ranges::to_vector;
|
||||
auto y_ticklabels = input.YTicks.value_or(std::vector<std::pair<double, std::string>>{})
|
||||
| biu::toLvalue | ranges::views::values | ranges::to_vector;
|
||||
if (input.OutputPictureFile) plot(values, input.OutputPictureFile.value(), x_ticks, y_ticks, y_ticklabels);
|
||||
if (input.OutputPictureFile) plot
|
||||
(
|
||||
values, input.OutputPictureFile.value(),
|
||||
x_ticks, y_ticks, y_ticklabels, input.AspectRatio, input.PictureResolution
|
||||
);
|
||||
if (input.OutputDataFile)
|
||||
biu::Hdf5file(input.OutputDataFile.value(), true)
|
||||
.write("Values", values)
|
||||
.write("XTicks", x_ticks)
|
||||
.write("YTicks", y_ticks)
|
||||
.write("YTickLabels", y_ticklabels)
|
||||
.write("Resolution", std::vector{input.Resolution.X, input.Resolution.Y})
|
||||
.write("Range", std::vector{input.FrequencyRange.Min, input.FrequencyRange.Max});
|
||||
.write("InterpolationResolution", input.InterpolationResolution)
|
||||
.write("FrequencyRange", input.FrequencyRange);
|
||||
}
|
||||
|
||||
void ufo::plot_point(std::string config_file)
|
||||
@ -274,10 +295,12 @@ void ufo::plot_point(std::string config_file)
|
||||
std::string UnfoldedDataFile;
|
||||
// 要画图的 q 点
|
||||
Eigen::Vector3d Qpoint;
|
||||
// x 方向为频率,y 方向没有用
|
||||
struct { std::size_t X, Y; } Resolution;
|
||||
// 插值的分辨率
|
||||
std::size_t InterpolationResolution;
|
||||
std::optional<double> AspectRatio;
|
||||
std::optional<std::array<std::size_t, 2>> PictureResolution;
|
||||
// 画图的频率范围
|
||||
struct { double Min, Max; } FrequencyRange;
|
||||
std::array<double, 2> FrequencyRange;
|
||||
// 搜索 q 点时的阈值,单位为埃^-1
|
||||
std::optional<double> ThresholdWhenSearchingQpoints;
|
||||
// 是否要在 z 轴上作一些标记
|
||||
@ -315,17 +338,17 @@ void ufo::plot_point(std::string config_file)
|
||||
// q 点的数据(需要用到它的频率和权重)
|
||||
const UnfoldOutput::QpointDataType& qpoint,
|
||||
// 用于插值的分辨率和范围
|
||||
unsigned resolution,
|
||||
const std::pair<double, double>& frequency_range
|
||||
std::size_t resolution,
|
||||
const std::array<double, 2>& frequency_range
|
||||
)
|
||||
{
|
||||
biu::Logger::Guard log;
|
||||
std::vector<double> result(resolution);
|
||||
for (auto& mode : qpoint.ModeData)
|
||||
{
|
||||
int index = (mode.Frequency - frequency_range.first) / (frequency_range.second - frequency_range.first)
|
||||
std::ptrdiff_t index = (mode.Frequency - frequency_range[0]) / (frequency_range[1] - frequency_range[0])
|
||||
* resolution;
|
||||
if (index >= 0 && index < static_cast<int>(resolution)) result[index] += mode.Weight;
|
||||
if (index >= 0 && index < static_cast<std::ptrdiff_t>(resolution)) result[index] += mode.Weight;
|
||||
}
|
||||
return log.rtn(result);
|
||||
};
|
||||
@ -334,7 +357,8 @@ void ufo::plot_point(std::string config_file)
|
||||
auto plot = []
|
||||
(
|
||||
const std::vector<double>& values, const std::string& filename,
|
||||
const std::vector<double>& x_ticks, const std::vector<std::string>& x_ticklabels, unsigned y_resolution
|
||||
const std::vector<double>& x_ticks, const std::vector<std::string>& x_ticklabels, std::size_t y_resolution,
|
||||
const std::optional<double>& aspect_ratio, const std::optional<std::array<std::size_t, 2>>& resolution
|
||||
)
|
||||
{
|
||||
biu::Logger::Guard log;
|
||||
@ -343,7 +367,7 @@ void ufo::plot_point(std::string config_file)
|
||||
g(y_resolution, std::vector<double>(values.size(), 0)),
|
||||
b(y_resolution, std::vector<double>(values.size(), 0)),
|
||||
a(y_resolution, std::vector<double>(values.size(), 0));
|
||||
for (unsigned i = 0; i < y_resolution; i++) for (unsigned j = 0; j < values.size(); j++)
|
||||
for (std::size_t i = 0; i < y_resolution; i++) for (std::size_t j = 0; j < values.size(); j++)
|
||||
{
|
||||
auto v = values[j];
|
||||
if (v < 0.05) v = 0;
|
||||
@ -364,6 +388,16 @@ void ufo::plot_point(std::string config_file)
|
||||
ax->x_axis().tick_length(1);
|
||||
ax->x_axis().ticklabels(x_ticklabels);
|
||||
ax->y_axis().tick_values({});
|
||||
if (aspect_ratio)
|
||||
{
|
||||
ax->axes_aspect_ratio_auto(false);
|
||||
ax->axes_aspect_ratio(*aspect_ratio);
|
||||
}
|
||||
if (resolution)
|
||||
{
|
||||
f->width((*resolution)[0]);
|
||||
f->height((*resolution)[1]);
|
||||
}
|
||||
f->save(filename, "png");
|
||||
};
|
||||
|
||||
@ -383,25 +417,28 @@ void ufo::plot_point(std::string config_file)
|
||||
auto values = calculate_values
|
||||
(
|
||||
unfolded_data.QpointData[qpoint_index],
|
||||
input.Resolution.X, {input.FrequencyRange.Min, input.FrequencyRange.Max}
|
||||
input.InterpolationResolution, input.FrequencyRange
|
||||
);
|
||||
auto x_ticks = input.XTicks.value_or(std::vector<std::pair<double, std::string>>{})
|
||||
| biu::toLvalue | ranges::views::keys
|
||||
| ranges::views::transform([&](auto i)
|
||||
{
|
||||
return (i - input.FrequencyRange.Min) / (input.FrequencyRange.Max - input.FrequencyRange.Min)
|
||||
* input.Resolution.X;
|
||||
return (i - input.FrequencyRange[0]) / (input.FrequencyRange[1] - input.FrequencyRange[0])
|
||||
* input.InterpolationResolution;
|
||||
})
|
||||
| ranges::to_vector;
|
||||
auto x_ticklabels = input.XTicks.value_or(std::vector<std::pair<double, std::string>>{})
|
||||
| biu::toLvalue | ranges::views::values | ranges::to_vector;
|
||||
if (input.OutputPictureFile)
|
||||
plot(values, input.OutputPictureFile.value(), x_ticks, x_ticklabels, input.Resolution.Y);
|
||||
if (input.OutputPictureFile) plot
|
||||
(
|
||||
values, input.OutputPictureFile.value(),
|
||||
x_ticks, x_ticklabels, 10, input.AspectRatio, input.PictureResolution
|
||||
);
|
||||
if (input.OutputDataFile)
|
||||
biu::Hdf5file(input.OutputDataFile.value(), true)
|
||||
.write("Values", values)
|
||||
.write("XTicks", x_ticks)
|
||||
.write("XTickLabels", x_ticklabels)
|
||||
.write("Resolution", std::vector{input.Resolution.X, input.Resolution.Y})
|
||||
.write("Range", std::vector{input.FrequencyRange.Min, input.FrequencyRange.Max});
|
||||
.write("InterpolationResolution", input.InterpolationResolution)
|
||||
.write("FrequencyRange", input.FrequencyRange);
|
||||
}
|
||||
|
@ -29,10 +29,11 @@ void ufo::unfold(std::string config_file)
|
||||
// PositionToSuperCell(line vector) * SuperCell = PositionToPrimativeCell(line vector) * PrimativeCell
|
||||
// ReciprocalPositionToSuperCell(line vector) * ReciprocalSuperCell
|
||||
// = ReciprocalPositionToPrimativeCell(line vector) * ReciprocalPrimativeCell
|
||||
Eigen::Matrix3i SuperCellTransformation;
|
||||
Eigen::Matrix3d SuperCellDeformation;
|
||||
Eigen::Vector3i SuperCellMultiplier;
|
||||
|
||||
// 在单胞内取几个平面波的基矢
|
||||
Eigen::Vector<unsigned, 3> PrimativeCellBasisNumber;
|
||||
Eigen::Vector<std::size_t, 3> PrimativeCellBasisNumber;
|
||||
|
||||
// 超胞中原子的坐标,每行表示一个原子的坐标,单位为超胞的格矢
|
||||
Eigen::MatrixX3d AtomPositionBySuperCell;
|
||||
@ -89,17 +90,18 @@ void ufo::unfold(std::string config_file)
|
||||
// 整理得到结果
|
||||
auto number_of_qpoints = frequency.size(), num_of_modes = frequency[0].size();
|
||||
std::vector<UnfoldOutput::MetaQpointDataType> qpoint_data(number_of_qpoints);
|
||||
for (unsigned i = 0; i < number_of_qpoints; i++)
|
||||
for (std::size_t i = 0; i < number_of_qpoints; i++)
|
||||
{
|
||||
qpoint_data[i].Qpoint = qpoint[i] | biu::toEigen<>;
|
||||
qpoint_data[i].ModeData.resize(num_of_modes);
|
||||
for (unsigned j = 0; j < num_of_modes; j++)
|
||||
for (std::size_t j = 0; j < num_of_modes; j++)
|
||||
{
|
||||
qpoint_data[i].ModeData[j].Frequency = frequency[i][j];
|
||||
auto n_modes = eigenvector_vector[i].size() / 3;
|
||||
Eigen::MatrixX3cd eigenvectors(n_modes, 3);
|
||||
for (unsigned k = 0; k < n_modes; k++) for (unsigned l = 0; l < 3; l++) eigenvectors(k, l)
|
||||
= eigenvector_vector[i][k * 3 + l][j].r + eigenvector_vector[i][k * 3 + l][j].i * 1i;
|
||||
auto number_of_atoms = eigenvector_vector[i].size() / 3;
|
||||
Eigen::MatrixX3cd eigenvectors(number_of_atoms, 3);
|
||||
for (std::size_t k = 0; k < number_of_atoms; k++) for (std::size_t l = 0; l < 3; l++)
|
||||
eigenvectors(k, l)
|
||||
= eigenvector_vector[i][k * 3 + l][j].r + eigenvector_vector[i][k * 3 + l][j].i * 1i;
|
||||
// 原则上讲,需要对读入的原子运动状态作相位转换, 使得它们与我们的约定一致(对超胞周期性重复),但这个转换 phonopy 已经做了
|
||||
// 这里还要需要做归一化处理 (指将数据简单地作为向量处理的归一化)
|
||||
qpoint_data[i].ModeData[j].AtomMovement = eigenvectors / eigenvectors.norm();
|
||||
@ -108,135 +110,6 @@ void ufo::unfold(std::string config_file)
|
||||
return qpoint_data;
|
||||
};
|
||||
|
||||
// 将 SuperCellTransformation 矩阵分解为 SuperCellDeformation 和 SuperCellMultiplier
|
||||
auto decompose_transformation = [](Eigen::Matrix3i transformation)
|
||||
-> std::pair<Eigen::Matrix3d, Eigen::Vector3i>
|
||||
{
|
||||
// 三种整数基础矩阵
|
||||
struct Multiply { unsigned at; int multiply; };
|
||||
struct Add { unsigned from, to; int multiply; };
|
||||
struct Exchange { unsigned from, to; };
|
||||
|
||||
// 将 SuperCellTransformation 分解为一系列基础矩阵的乘积,并将这些基础矩阵从左到右输出
|
||||
auto decompose = [](Eigen::Matrix3i matrix)
|
||||
-> concurrencpp::generator<std::variant<Add, Exchange, Multiply>>
|
||||
{
|
||||
// 首先将第一列转变为只有一个元素不为零
|
||||
while (true)
|
||||
{
|
||||
// 统计第一列零的个数,以及非零值中,绝对值最大和最小的行
|
||||
std::multimap<unsigned, unsigned> values;
|
||||
for (unsigned i = 0; i < 3; i++) if (matrix(i, 0) != 0)
|
||||
values.insert({std::abs(matrix(i, 0)), i});
|
||||
// 如果都是零,报错
|
||||
if (values.size() == 0) [[unlikely]] throw std::runtime_error("Transformation matrix is singular.");
|
||||
// 如果只有一个非零值,那么将它移到第一行
|
||||
if (values.size() == 1)
|
||||
{
|
||||
if (auto i = values.begin()->second; i != 0)
|
||||
{
|
||||
auto transform = Eigen::Matrix3i::Identity().eval();
|
||||
transform(0, 0) = 0;
|
||||
transform(0, i) = 1;
|
||||
transform(i, i) = 0;
|
||||
transform(i, 0) = 1;
|
||||
matrix = transform * matrix;
|
||||
co_yield Exchange{0, i};
|
||||
}
|
||||
break;
|
||||
}
|
||||
// 否则,将最小值乘以整数倍,加到最大值上
|
||||
else
|
||||
{
|
||||
auto i_max = values.rbegin()->second;
|
||||
auto i_min = values.begin()->second;
|
||||
auto multiply = -matrix(i_max, 0) / matrix(i_min, 0);
|
||||
auto transform = Eigen::Matrix3i::Identity().eval();
|
||||
transform(i_max, i_min) = multiply;
|
||||
matrix = transform * matrix;
|
||||
// 分解出来的矩阵需要是操作的逆
|
||||
co_yield Add{i_min, i_max, -multiply};
|
||||
}
|
||||
}
|
||||
// 然后将第二列后两行转变为只有一个元素不为零
|
||||
while (true)
|
||||
{
|
||||
// 如果都是零,报错
|
||||
if (matrix(1, 1) == 0 && matrix(2, 1) == 0) [[unlikely]]
|
||||
throw std::runtime_error("Transformation matrix is singular.");
|
||||
// 如果只有一个不是零,将它移到第二行
|
||||
else if (matrix(2, 1) == 0) break;
|
||||
else if (matrix(1, 1) == 0)
|
||||
{
|
||||
Eigen::Matrix3i transform{{1, 0, 0}, {0, 0, 1}, {0, 1, 0}};
|
||||
matrix = transform * matrix;
|
||||
co_yield Exchange{1, 2};
|
||||
break;
|
||||
}
|
||||
// 否则,将最小值乘以整数倍,加到最大值上
|
||||
else
|
||||
{
|
||||
unsigned i_max, i_min;
|
||||
if (std::abs(matrix(1, 1)) > std::abs(matrix(2, 1))) { i_max = 1; i_min = 2; }
|
||||
else { i_max = 2; i_min = 1; }
|
||||
auto multiply = -matrix(i_max, 1) / matrix(i_min, 1);
|
||||
auto transform = Eigen::Matrix3i::Identity().eval();
|
||||
transform(i_max, i_min) = multiply;
|
||||
matrix = transform * matrix;
|
||||
co_yield Add{i_min, i_max, -multiply};
|
||||
}
|
||||
}
|
||||
// 然后将第三行第三列元素化为 1
|
||||
if (matrix(2, 2) == 0) [[unlikely]] throw std::runtime_error("Transformation matrix is singular.");
|
||||
else if (matrix(2, 2) != 1)
|
||||
{
|
||||
co_yield Multiply{2, matrix(2, 2)};
|
||||
matrix(2, 2) = 1;
|
||||
}
|
||||
// 将第三列的其它元素化为 0
|
||||
if (matrix(0, 2) != 0)
|
||||
{ co_yield Add{2, 0, matrix(0, 2)}; matrix(0, 2) = 0; }
|
||||
if (matrix(1, 2) != 0)
|
||||
{ co_yield Add{2, 1, matrix(1, 2)}; matrix(1, 2) = 0; }
|
||||
// 将第二行第二列元素化为 1
|
||||
if (matrix(1, 1) == 0) [[unlikely]] throw std::runtime_error("Transformation matrix is singular.");
|
||||
else if (matrix(1, 1) != 1)
|
||||
{ co_yield Multiply{1, matrix(1, 1)}; matrix(1, 1) = 1; }
|
||||
// 将第一行第二列元素化为 0
|
||||
if (matrix(0, 1) != 0)
|
||||
{ co_yield Add{1, 0, matrix(0, 1)}; matrix(0, 1) = 0; }
|
||||
// 将第一行第一列元素化为 1
|
||||
if (matrix(0, 0) == 0) [[unlikely]] throw std::runtime_error("Transformation matrix is singular.");
|
||||
else if (matrix(0, 0) != 1)
|
||||
{ co_yield Multiply{0, matrix(0, 0)}; matrix(0, 0) = 1; }
|
||||
};
|
||||
|
||||
auto deformatin = Eigen::Matrix3d::Identity().eval();
|
||||
auto multiplier = Eigen::Vector3i::Ones().eval();
|
||||
for (auto i : decompose(transformation))
|
||||
{
|
||||
if (std::holds_alternative<Multiply>(i))
|
||||
{
|
||||
auto [at, multiply] = std::get<Multiply>(i);
|
||||
multiplier(at) *= multiply;
|
||||
}
|
||||
else if (std::holds_alternative<Add>(i))
|
||||
{
|
||||
auto [from, to, multiply] = std::get<Add>(i);
|
||||
auto transform = Eigen::Matrix3d::Identity().eval();
|
||||
transform(to, from) = static_cast<double>(multiply) / multiplier(from) * multiplier(to);
|
||||
deformatin = deformatin * transform;
|
||||
}
|
||||
else if (std::holds_alternative<Exchange>(i))
|
||||
{
|
||||
auto [from, to] = std::get<Exchange>(i);
|
||||
deformatin.col(from).swap(deformatin.col(to));
|
||||
std::swap(multiplier(from), multiplier(to));
|
||||
}
|
||||
}
|
||||
return {deformatin, multiplier};
|
||||
};
|
||||
|
||||
// 构建基
|
||||
// 每个 q 点对应一组 sub qpoint。不同的 q 点所对应的 sub qpoint 是不一样的,但 sub qpoint 与 q 点的相对位移在不同 q 点之间是相同的。
|
||||
// 由于基只与这个相对位置有关(也就是说,不同 q 点的基是一样的),因此可以先计算出所有的基,这样降低计算量。
|
||||
@ -245,9 +118,10 @@ void ufo::unfold(std::string config_file)
|
||||
auto construct_basis = []
|
||||
(
|
||||
Eigen::Matrix3d primative_cell, Eigen::Vector3i super_cell_multiplier,
|
||||
Eigen::Vector<unsigned, 3> primative_cell_basis_number, Eigen::MatrixX3d atom_position
|
||||
Eigen::Vector<std::size_t, 3> primative_cell_basis_number, Eigen::MatrixX3d atom_position
|
||||
)
|
||||
{
|
||||
biu::Logger::Guard log;
|
||||
std::vector<std::vector<Eigen::VectorXcd>> basis(super_cell_multiplier.prod());
|
||||
// diff_of_sub_qpoint 表示 sub qpoint 与 qpoint 的相对位置,单位为超胞的倒格矢
|
||||
for (auto [diff_of_sub_qpoint_by_reciprocal_modified_super_cell, i_of_sub_qpoint]
|
||||
@ -261,14 +135,6 @@ void ufo::unfold(std::string config_file)
|
||||
auto diff_of_sub_qpoint_by_reciprocal_primative_cell = xyz_of_basis.cast<double>()
|
||||
+ super_cell_multiplier.cast<double>().cwiseInverse().asDiagonal()
|
||||
* diff_of_sub_qpoint_by_reciprocal_modified_super_cell.cast<double>();
|
||||
// DiffOfSubQpoint
|
||||
// = (DiffOfSubQpointByReciprocalPrimativeCell.transpose() * ReciprocalPrimativeCell).transpose()
|
||||
// ReciprocalPrimativeCell = PrimativeCell.transpose().inverse()
|
||||
// SuperCell = SuperCellTransformation * PrimativeCell
|
||||
// ReciprocalSuperCell = SuperCell.transpose().inverse()
|
||||
// AtomPosition = AtomPositionBySuperCell * SuperCell.transpose()
|
||||
// 整理得到:
|
||||
//
|
||||
// 将单位转换为埃^-1
|
||||
auto diff_of_sub_qpoint = (diff_of_sub_qpoint_by_reciprocal_primative_cell.transpose()
|
||||
* (primative_cell.transpose().inverse())).transpose();
|
||||
@ -287,7 +153,7 @@ void ufo::unfold(std::string config_file)
|
||||
const std::vector<std::vector<Eigen::VectorXcd>>& basis,
|
||||
// 实际上只需要其中的 AtomMovement
|
||||
const std::vector<UnfoldOutput::MetaQpointDataType>& qpoint_data,
|
||||
std::atomic<unsigned>& number_of_finished_modes
|
||||
std::atomic<std::size_t>& number_of_finished_modes
|
||||
)
|
||||
{
|
||||
// 将所有的模式取出,组成一个一维数组,稍后并行计算
|
||||
@ -299,21 +165,20 @@ void ufo::unfold(std::string config_file)
|
||||
// 对每个模式并行
|
||||
std::transform
|
||||
(
|
||||
std::execution::par, mode_data.begin(), mode_data.end(),
|
||||
std::execution::par_unseq, mode_data.begin(), mode_data.end(),
|
||||
projection_coefficient.begin(), [&](const auto& mode_data)
|
||||
{
|
||||
// 这里, mode_data 和 projection_coefficient 均指对应于一个模式的数据
|
||||
std::vector<double> projection_coefficient(basis.size());
|
||||
for (unsigned i_of_sub_qpoint = 0; i_of_sub_qpoint < basis.size(); i_of_sub_qpoint++)
|
||||
for (std::size_t i_of_sub_qpoint = 0; i_of_sub_qpoint < basis.size(); i_of_sub_qpoint++)
|
||||
// 对于 basis 中, 对应于单胞倒格子的部分, 以及对应于不同方向的部分, 分别求内积, 然后求模方和
|
||||
for (unsigned i_of_basis = 0; i_of_basis < basis[i_of_sub_qpoint].size(); i_of_basis++)
|
||||
for (std::size_t i_of_basis = 0; i_of_basis < basis[i_of_sub_qpoint].size(); i_of_basis++)
|
||||
projection_coefficient[i_of_sub_qpoint] +=
|
||||
(basis[i_of_sub_qpoint][i_of_basis].transpose().conjugate() * mode_data.get())
|
||||
.array().abs2().sum();
|
||||
// 如果是严格地将向量分解到一组完备的基矢上, 那么不需要对计算得到的权重再做归一化处理
|
||||
// 但这里并不是这样一个严格的概念. 因此对分解到各个 sub qpoint 上的权重做归一化处理
|
||||
auto sum = std::accumulate
|
||||
(projection_coefficient.begin(), projection_coefficient.end(), 0.);
|
||||
auto sum = ranges::accumulate(projection_coefficient, 0.);
|
||||
for (auto& _ : projection_coefficient) _ /= sum;
|
||||
number_of_finished_modes++;
|
||||
return projection_coefficient;
|
||||
@ -324,8 +189,9 @@ void ufo::unfold(std::string config_file)
|
||||
std::vector<std::vector<std::vector<double>>> projection_coefficient_output;
|
||||
for
|
||||
(
|
||||
unsigned i_of_meta_qpoint = 0, num_of_mode_manipulated = 0;
|
||||
i_of_meta_qpoint < qpoint_data.size(); i_of_meta_qpoint++
|
||||
std::size_t i_of_meta_qpoint = 0, num_of_mode_manipulated = 0;
|
||||
i_of_meta_qpoint < qpoint_data.size();
|
||||
i_of_meta_qpoint++, num_of_mode_manipulated += qpoint_data[i_of_meta_qpoint].ModeData.size()
|
||||
)
|
||||
projection_coefficient_output.emplace_back
|
||||
(
|
||||
@ -339,8 +205,6 @@ void ufo::unfold(std::string config_file)
|
||||
auto construct_output = []
|
||||
(
|
||||
const Input& input,
|
||||
const Eigen::Vector3i& super_cell_multiplier,
|
||||
const Eigen::Matrix3d& super_cell_deformation,
|
||||
const std::vector<std::vector<std::vector<double>>>& projection_coefficient,
|
||||
const std::vector<UnfoldOutput::MetaQpointDataType>& qpoint_data,
|
||||
const std::optional<std::vector<std::size_t>>& selected_atoms
|
||||
@ -348,31 +212,30 @@ void ufo::unfold(std::string config_file)
|
||||
{
|
||||
UnfoldOutput output;
|
||||
output.PrimativeCell = input.PrimativeCell;
|
||||
output.SuperCellTransformation = input.SuperCellTransformation;
|
||||
output.SuperCellMultiplier = super_cell_multiplier;
|
||||
output.SuperCellDeformation = super_cell_deformation;
|
||||
output.SuperCellMultiplier = input.SuperCellMultiplier;
|
||||
output.SuperCellDeformation = input.SuperCellDeformation;
|
||||
output.SelectedAtoms = selected_atoms;
|
||||
output.MetaQpointData = qpoint_data;
|
||||
for (unsigned i_of_meta_qpoint = 0; i_of_meta_qpoint < qpoint_data.size(); i_of_meta_qpoint++)
|
||||
for (std::size_t i_of_meta_qpoint = 0; i_of_meta_qpoint < qpoint_data.size(); i_of_meta_qpoint++)
|
||||
{
|
||||
// 如果需要投影到特定的原子上,需要先计算当前 meta qpoint 的不同模式的投影系数
|
||||
std::optional<std::vector<double>> projection_coefficient_on_atoms;
|
||||
if (selected_atoms)
|
||||
{
|
||||
projection_coefficient_on_atoms.emplace();
|
||||
for (std::size_t i = 0; i < qpoint_data[i_of_meta_qpoint].ModeData.size(); i++)
|
||||
for (std::size_t i_of_mode = 0; i_of_mode < qpoint_data[i_of_meta_qpoint].ModeData.size(); i_of_mode++)
|
||||
{
|
||||
projection_coefficient_on_atoms.value().emplace_back(0);
|
||||
for (auto atom : *selected_atoms)
|
||||
projection_coefficient_on_atoms.value().back()
|
||||
+= qpoint_data[i_of_meta_qpoint].ModeData[i].AtomMovement.row(atom).array().abs2().sum();
|
||||
+= qpoint_data[i_of_meta_qpoint].ModeData[i_of_mode].AtomMovement.row(atom).array().abs2().sum();
|
||||
}
|
||||
}
|
||||
|
||||
for
|
||||
(
|
||||
auto [diff_of_sub_qpoint_by_reciprocal_modified_super_cell, i_of_sub_qpoint]
|
||||
: biu::sequence(super_cell_multiplier)
|
||||
: biu::sequence(input.SuperCellMultiplier)
|
||||
)
|
||||
{
|
||||
auto& _ = output.QpointData.emplace_back();
|
||||
@ -399,10 +262,10 @@ void ufo::unfold(std::string config_file)
|
||||
*/
|
||||
auto sub_qpoint_by_reciprocal_primative_cell =
|
||||
(
|
||||
super_cell_multiplier.cast<double>().cwiseInverse().asDiagonal()
|
||||
input.SuperCellMultiplier.cast<double>().cwiseInverse().asDiagonal()
|
||||
* (
|
||||
diff_of_sub_qpoint_by_reciprocal_modified_super_cell.cast<double>()
|
||||
+ super_cell_deformation.inverse() * qpoint_data[i_of_meta_qpoint].Qpoint
|
||||
+ input.SuperCellDeformation.inverse() * qpoint_data[i_of_meta_qpoint].Qpoint
|
||||
)
|
||||
).eval();
|
||||
_.Qpoint = sub_qpoint_by_reciprocal_primative_cell.array()
|
||||
@ -410,7 +273,7 @@ void ufo::unfold(std::string config_file)
|
||||
_.Source = qpoint_data[i_of_meta_qpoint].Qpoint;
|
||||
_.SourceIndex = i_of_meta_qpoint;
|
||||
|
||||
for (unsigned i_of_mode = 0; i_of_mode < qpoint_data[i_of_meta_qpoint].ModeData.size(); i_of_mode++)
|
||||
for (std::size_t i_of_mode = 0; i_of_mode < qpoint_data[i_of_meta_qpoint].ModeData.size(); i_of_mode++)
|
||||
{
|
||||
auto& __ = _.ModeData.emplace_back();
|
||||
__.Frequency = qpoint_data[i_of_meta_qpoint].ModeData[i_of_mode].Frequency;
|
||||
@ -423,31 +286,31 @@ void ufo::unfold(std::string config_file)
|
||||
return output;
|
||||
};
|
||||
|
||||
std::clog << "Reading input file... " << std::flush;
|
||||
biu::Logger::Guard log;
|
||||
log.info("Reading input file... ");
|
||||
auto input = YAML::LoadFile(config_file).as<Input>();
|
||||
auto qpoint_data
|
||||
= read_qpoint_data(input.QpointDataInputFile.value_or("band.hdf5"));
|
||||
std::clog << "Done." << std::endl;
|
||||
auto qpoint_data = read_qpoint_data(input.QpointDataInputFile.value_or("band.hdf5"));
|
||||
log.info("Done.");
|
||||
|
||||
std::clog << "Constructing basis... " << std::flush;
|
||||
auto [super_cell_deformation, super_cell_multiplier]
|
||||
= decompose_transformation(input.SuperCellTransformation);
|
||||
|
||||
auto basis = construct_basis
|
||||
(
|
||||
input.PrimativeCell, super_cell_multiplier,
|
||||
input.PrimativeCell, input.SuperCellMultiplier,
|
||||
input.PrimativeCellBasisNumber,
|
||||
input.AtomPositionBySuperCell
|
||||
* (input.SuperCellTransformation.cast<double>() * input.PrimativeCell).transpose()
|
||||
* (input.SuperCellDeformation * input.SuperCellMultiplier.cast<double>().asDiagonal() * input.PrimativeCell)
|
||||
);
|
||||
std::clog << "Done." << std::endl;
|
||||
|
||||
std::clog << "Calculating projection coefficient... " << std::flush;
|
||||
// 用来在屏幕上输出进度的计数器和线程
|
||||
std::atomic<unsigned> number_of_finished_modes(0);
|
||||
std::atomic<std::size_t> number_of_finished_modes(0);
|
||||
auto number_of_modes = ranges::accumulate
|
||||
(
|
||||
qpoint_data
|
||||
| ranges::views::transform([](const auto& qpoint) { return qpoint.ModeData.size(); }),
|
||||
| ranges::views::transform([](const auto& qpoint)
|
||||
{ return qpoint.ModeData.size(); }),
|
||||
0ul
|
||||
);
|
||||
std::atomic<bool> finished;
|
||||
@ -471,10 +334,7 @@ void ufo::unfold(std::string config_file)
|
||||
for (auto& output_file : input.QpointDataOutputFile)
|
||||
{
|
||||
auto output = construct_output
|
||||
(
|
||||
input, super_cell_multiplier, super_cell_deformation,
|
||||
projection_coefficient, qpoint_data, output_file.SelectedAtoms
|
||||
);
|
||||
(input, projection_coefficient, qpoint_data, output_file.SelectedAtoms);
|
||||
if (output_file.OutputAsYaml.value_or(false)) std::ofstream(output_file.Filename) << YAML::Node(output);
|
||||
else std::ofstream(output_file.Filename, std::ios::binary) << biu::serialize<char>(output);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
SuperCellTransformation:
|
||||
- [ 3, 0, 0 ]
|
||||
- [ 2, 4, 0 ]
|
||||
SuperCellMultiplier: [3, 4, 1]
|
||||
SuperCellDeformation:
|
||||
- [ 1, 0, 0 ]
|
||||
- [ 0.6666, 1, 0 ]
|
||||
- [ 0, 0, 1 ]
|
||||
Qpoints:
|
||||
- [0, 0, 0]
|
||||
|
@ -1,45 +0,0 @@
|
||||
Qpoints:
|
||||
-
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
-
|
||||
- 0.15000000000000002
|
||||
- 0.10000000000000001
|
||||
- 0
|
||||
-
|
||||
- 0.30000000000000004
|
||||
- 0.20000000000000001
|
||||
- 0
|
||||
-
|
||||
- 0.44999999999999996
|
||||
- 0.29999999999999999
|
||||
- 0
|
||||
-
|
||||
- 0.60000000000000009
|
||||
- 0.40000000000000002
|
||||
- 0
|
||||
-
|
||||
- 0.75
|
||||
- 0.5
|
||||
- 0
|
||||
-
|
||||
- 0.89999999999999991
|
||||
- 0.59999999999999998
|
||||
- 0
|
||||
-
|
||||
- 0.049999999999999822
|
||||
- 0.69999999999999996
|
||||
- 0
|
||||
-
|
||||
- 0.20000000000000018
|
||||
- 0.80000000000000004
|
||||
- 0
|
||||
-
|
||||
- 0.35000000000000009
|
||||
- 0.90000000000000002
|
||||
- 0
|
||||
-
|
||||
- 0.5
|
||||
- 0
|
||||
- 0
|
Loading…
Reference in New Issue
Block a user