eulim 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +12 -12
- data/.rspec +2 -2
- data/.travis.yml +5 -5
- data/CODE_OF_CONDUCT.md +74 -74
- data/Gemfile +4 -4
- data/LICENSE +21 -21
- data/LICENSE.txt +21 -21
- data/README.md +92 -71
- data/Rakefile +6 -6
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/eulim.gemspec +44 -43
- data/lib/class.rb +6 -0
- data/lib/eulim.rb +26 -8
- data/lib/eulim/chemical.rb +6 -0
- data/lib/eulim/chemical/reactors.rb +11 -0
- data/lib/eulim/chemical/reactors/batch_reactor.rb +14 -0
- data/lib/eulim/chemical/reactors/continuous_stirred_tank_reactor.rb +16 -0
- data/lib/eulim/chemical/reactors/plug_flow_reactor.rb +12 -0
- data/lib/eulim/chemical/reactors/reactor.rb +27 -0
- data/lib/eulim/chemistry.rb +6 -6
- data/lib/eulim/chemistry/compound.rb +61 -61
- data/lib/eulim/chemistry/element.rb +53 -54
- data/lib/eulim/chemistry/elements.csv +109 -109
- data/lib/eulim/chemistry/reaction.rb +82 -73
- data/lib/eulim/chemistry/substance.rb +18 -0
- data/lib/eulim/structures.rb +6 -6
- data/lib/eulim/structures/pipe.rb +13 -13
- data/lib/eulim/structures/structure.rb +12 -12
- data/lib/eulim/version.rb +3 -3
- data/lib/string.rb +16 -0
- metadata +14 -3
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require 'bundler/gem_tasks'
|
2
|
-
require 'rspec/core/rake_task'
|
3
|
-
|
4
|
-
RSpec::Core::RakeTask.new(:spec)
|
5
|
-
|
6
|
-
task default: :spec
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
|
6
|
+
task default: :spec
|
data/bin/console
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'bundler/setup'
|
4
|
-
require 'eulim'
|
5
|
-
|
6
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
-
# with your gem easier. You can also use a different console, if you like.
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require 'pry'
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require 'irb'
|
14
|
-
IRB.start(__FILE__)
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'eulim'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require 'pry'
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
set -euo pipefail
|
3
|
-
IFS=$'\n\t'
|
4
|
-
set -vx
|
5
|
-
|
6
|
-
bundle install
|
7
|
-
|
8
|
-
# Do any other automated setup that you need to do here
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
set -euo pipefail
|
3
|
+
IFS=$'\n\t'
|
4
|
+
set -vx
|
5
|
+
|
6
|
+
bundle install
|
7
|
+
|
8
|
+
# Do any other automated setup that you need to do here
|
data/eulim.gemspec
CHANGED
@@ -1,43 +1,44 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'eulim/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = 'eulim'
|
8
|
-
spec.version = Eulim::VERSION
|
9
|
-
spec.authors = ['Syed Fazil Basheer']
|
10
|
-
spec.email = ['fazil.basheer@quester.xyz']
|
11
|
-
|
12
|
-
|
13
|
-
spec.
|
14
|
-
spec.
|
15
|
-
spec.
|
16
|
-
|
17
|
-
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
spec.
|
34
|
-
spec.
|
35
|
-
|
36
|
-
|
37
|
-
spec.add_development_dependency '
|
38
|
-
spec.add_development_dependency '
|
39
|
-
spec.add_development_dependency '
|
40
|
-
|
41
|
-
|
42
|
-
spec.add_dependency '
|
43
|
-
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'eulim/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'eulim'
|
8
|
+
spec.version = Eulim::VERSION
|
9
|
+
spec.authors = ['Syed Fazil Basheer','Somesh Choudhary']
|
10
|
+
spec.email = ['fazil.basheer@quester.xyz', 'c.somesh5@gmail.com']
|
11
|
+
|
12
|
+
|
13
|
+
spec.summary = 'A gem for scientific data.'
|
14
|
+
spec.description = 'A gem for scientific data.'
|
15
|
+
spec.homepage = 'https://github.com/syedfazilbasheer-quester/eulim-gem'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
# Prevent pushing this gem to RubyGems.org.
|
19
|
+
# To allow pushes either set the 'allowed_push_host'
|
20
|
+
# to allow pushing to a single host
|
21
|
+
# or delete this section to allow pushing to any host.
|
22
|
+
# if spec.respond_to?(:metadata)
|
23
|
+
# spec.metadata['allowed_push_host'] =
|
24
|
+
# 'https://github.com/syedfazilbasheer-quester/eulim-gem'
|
25
|
+
# else
|
26
|
+
# raise 'RubyGems 2.0 or newer is required to protect against ' \
|
27
|
+
# 'public gem pushes.'
|
28
|
+
# end
|
29
|
+
|
30
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
31
|
+
f.match(%r{^(test|spec|features)/})
|
32
|
+
end
|
33
|
+
spec.bindir = 'exe'
|
34
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
35
|
+
spec.require_paths = ['lib']
|
36
|
+
|
37
|
+
spec.add_development_dependency 'bundler', '~> 1.14'
|
38
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
39
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
40
|
+
spec.add_development_dependency 'rubocop', '~>0.49.1'
|
41
|
+
|
42
|
+
spec.add_dependency 'require_all', '~> 1.4.0'
|
43
|
+
spec.add_dependency 'unitwise', '~> 2.1.0'
|
44
|
+
end
|
data/lib/class.rb
ADDED
data/lib/eulim.rb
CHANGED
@@ -1,8 +1,26 @@
|
|
1
|
-
require 'require_all'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
module
|
7
|
-
|
8
|
-
end
|
1
|
+
require 'require_all'
|
2
|
+
require 'unitwise'
|
3
|
+
|
4
|
+
require_all '../eulim/lib'
|
5
|
+
|
6
|
+
# Root module. Everything in the gem goes inside this
|
7
|
+
module Eulim
|
8
|
+
end
|
9
|
+
|
10
|
+
Ch = Eulim::Chemistry
|
11
|
+
Elem = Ch::Element
|
12
|
+
Comp = Ch::Compound
|
13
|
+
Rxn = Ch::Reaction
|
14
|
+
Subs = Ch::Substance
|
15
|
+
|
16
|
+
Cl = Eulim::Chemical
|
17
|
+
Rcts = Cl::Reactors
|
18
|
+
Br = Rcts::Batch
|
19
|
+
Cstr = Rcts::CSTR
|
20
|
+
Pfr = Rcts::PFR
|
21
|
+
|
22
|
+
def Unitwise(*args)
|
23
|
+
regex = /(\d+)(.*)/
|
24
|
+
args = args.first.scan(regex).first.collect(&:strip) if args.count == 1
|
25
|
+
Unitwise::Measurement.new(*args.first.to_f, *args.last)
|
26
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Eulim
|
2
|
+
module Chemical
|
3
|
+
module Reactors
|
4
|
+
# This class is for batch reactors
|
5
|
+
# assumptions: well mixed, closed system
|
6
|
+
class BatchReactor < Reactor
|
7
|
+
def initialize(args = {})
|
8
|
+
super args
|
9
|
+
@system = args[:system] == :isolated ? :isolated : :closed
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Eulim
|
2
|
+
module Chemical
|
3
|
+
module Reactors
|
4
|
+
# This class is for cst reactors
|
5
|
+
class ContinuousStirredTankReactor < Reactor
|
6
|
+
def initialize(args = {})
|
7
|
+
super args
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.humanized_name
|
11
|
+
'Continuous stirred-tank reactor'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Eulim
|
2
|
+
module Chemical
|
3
|
+
module Reactors
|
4
|
+
# This is the base class for the diff kinds of reactors
|
5
|
+
class Reactor
|
6
|
+
attr_accessor :system, :volume, :input, :output, :conversion
|
7
|
+
|
8
|
+
def initialize(args = {})
|
9
|
+
@volume = volume_if_valid(args[:volume]) if args[:volume]
|
10
|
+
@system = args[:system] || :open
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def volume_if_valid(vol)
|
16
|
+
begin
|
17
|
+
vol = Unitwise(vol)
|
18
|
+
rescue
|
19
|
+
raise ArgumentError, 'Invalid volume argument'
|
20
|
+
end
|
21
|
+
return vol if vol.composition.to_h == { 'L' => 3 }
|
22
|
+
raise ArgumentError, 'Invalid volume unit'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/eulim/chemistry.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
module Eulim
|
2
|
-
# This module will contain all chemistry related info
|
3
|
-
# Ex: Elements, Compounds, Reactions, etc
|
4
|
-
module Chemistry
|
5
|
-
end
|
6
|
-
end
|
1
|
+
module Eulim
|
2
|
+
# This module will contain all chemistry related info
|
3
|
+
# Ex: Elements, Compounds, Reactions, etc
|
4
|
+
module Chemistry
|
5
|
+
end
|
6
|
+
end
|
@@ -1,61 +1,61 @@
|
|
1
|
-
require 'unitwise'
|
2
|
-
|
3
|
-
module Eulim
|
4
|
-
module Chemistry
|
5
|
-
# This class has functionality for compounds
|
6
|
-
# Ex: constituent elements, molecular mass, etc
|
7
|
-
class Compound
|
8
|
-
COMPOUND_REGEXP =
|
9
|
-
/[A-Z][a-z]{0,2}\d*|\((?:[^()]*(?:\(.*\))?[^()]*)+\)\d*/
|
10
|
-
|
11
|
-
attr_accessor :molecular_mass, :constituents, :formula
|
12
|
-
|
13
|
-
def initialize(arg)
|
14
|
-
@formula = arg
|
15
|
-
build_constituents
|
16
|
-
calculate_molecular_mass
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def calculate_molecular_mass
|
22
|
-
@molecular_mass = Unitwise(0, 'u')
|
23
|
-
@constituents.each do |_symbol, info|
|
24
|
-
@molecular_mass += info[:element].atomic_mass * info[:atom_count]
|
25
|
-
end
|
26
|
-
@molecular_mass
|
27
|
-
end
|
28
|
-
|
29
|
-
def build_constituents
|
30
|
-
@constituents = {}
|
31
|
-
get_const_atoms.each do |symbol, count|
|
32
|
-
@constituents[symbol] = {
|
33
|
-
element: Element.get_by_symbol(symbol),
|
34
|
-
atom_count: count
|
35
|
-
}
|
36
|
-
end
|
37
|
-
@constituents
|
38
|
-
end
|
39
|
-
|
40
|
-
def get_const_atoms(formula = @formula, r = {})
|
41
|
-
formula.scan(COMPOUND_REGEXP).each do |const|
|
42
|
-
multipler = get_multipler const
|
43
|
-
if const[0] != '(' && multipler.zero?
|
44
|
-
r[const] = r[const] ? r[const] + 1 : 1
|
45
|
-
else
|
46
|
-
(multipler.zero? ? 1 : multipler).times do
|
47
|
-
sub_const = const.match(/^\(?(.*?)\)?($|\d*$)/).to_a
|
48
|
-
get_const_atoms sub_const[const == sub_const.first ? 1 : 0], r
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
r
|
53
|
-
end
|
54
|
-
|
55
|
-
def get_multipler(const)
|
56
|
-
multipler = const.match(/\d*$/).to_a.first.to_i
|
57
|
-
multipler
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
1
|
+
require 'unitwise'
|
2
|
+
|
3
|
+
module Eulim
|
4
|
+
module Chemistry
|
5
|
+
# This class has functionality for compounds
|
6
|
+
# Ex: constituent elements, molecular mass, etc
|
7
|
+
class Compound
|
8
|
+
COMPOUND_REGEXP =
|
9
|
+
/[A-Z][a-z]{0,2}\d*|\((?:[^()]*(?:\(.*\))?[^()]*)+\)\d*/
|
10
|
+
|
11
|
+
attr_accessor :molecular_mass, :constituents, :formula
|
12
|
+
|
13
|
+
def initialize(arg)
|
14
|
+
@formula = arg
|
15
|
+
build_constituents
|
16
|
+
calculate_molecular_mass
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def calculate_molecular_mass
|
22
|
+
@molecular_mass = Unitwise(0, 'u')
|
23
|
+
@constituents.each do |_symbol, info|
|
24
|
+
@molecular_mass += info[:element].atomic_mass * info[:atom_count]
|
25
|
+
end
|
26
|
+
@molecular_mass
|
27
|
+
end
|
28
|
+
|
29
|
+
def build_constituents
|
30
|
+
@constituents = {}
|
31
|
+
get_const_atoms.each do |symbol, count|
|
32
|
+
@constituents[symbol] = {
|
33
|
+
element: Element.get_by_symbol(symbol),
|
34
|
+
atom_count: count
|
35
|
+
}
|
36
|
+
end
|
37
|
+
@constituents
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_const_atoms(formula = @formula, r = {})
|
41
|
+
formula.scan(COMPOUND_REGEXP).each do |const|
|
42
|
+
multipler = get_multipler const
|
43
|
+
if const[0] != '(' && multipler.zero?
|
44
|
+
r[const] = r[const] ? r[const] + 1 : 1
|
45
|
+
else
|
46
|
+
(multipler.zero? ? 1 : multipler).times do
|
47
|
+
sub_const = const.match(/^\(?(.*?)\)?($|\d*$)/).to_a
|
48
|
+
get_const_atoms sub_const[const == sub_const.first ? 1 : 0], r
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
r
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_multipler(const)
|
56
|
+
multipler = const.match(/\d*$/).to_a.first.to_i
|
57
|
+
multipler
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -1,54 +1,53 @@
|
|
1
|
-
require 'csv'
|
2
|
-
require 'unitwise'
|
3
|
-
|
4
|
-
module Eulim
|
5
|
-
module Chemistry
|
6
|
-
# This class has functionality for elements
|
7
|
-
# Ex: symbol, atomic mass, atomic number
|
8
|
-
class Element
|
9
|
-
attr_accessor :atomic_mass, :symbol, :name, :atomic_number
|
10
|
-
|
11
|
-
ATTRS = %w[symbol name atomic_number atomic_mass].freeze
|
12
|
-
# Data taken from 'www.science.co.il/elements/'
|
13
|
-
ELEMENTS = []
|
14
|
-
|
15
|
-
def initialize(arg)
|
16
|
-
@name = arg[1]
|
17
|
-
@symbol = arg[0]
|
18
|
-
@atomic_number = arg[2].to_i
|
19
|
-
@atomic_mass = Unitwise(arg[3].to_f, 'u')
|
20
|
-
end
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
1
|
+
require 'csv'
|
2
|
+
require 'unitwise'
|
3
|
+
|
4
|
+
module Eulim
|
5
|
+
module Chemistry
|
6
|
+
# This class has functionality for elements
|
7
|
+
# Ex: symbol, atomic mass, atomic number
|
8
|
+
class Element
|
9
|
+
attr_accessor :atomic_mass, :symbol, :name, :atomic_number
|
10
|
+
|
11
|
+
ATTRS = %w[symbol name atomic_number atomic_mass].freeze
|
12
|
+
# Data taken from 'www.science.co.il/elements/'
|
13
|
+
ELEMENTS = []
|
14
|
+
|
15
|
+
def initialize(arg)
|
16
|
+
@name = arg[1]
|
17
|
+
@symbol = arg[0]
|
18
|
+
@atomic_number = arg[2].to_i
|
19
|
+
@atomic_mass = Unitwise(arg[3].to_f, 'u')
|
20
|
+
end
|
21
|
+
|
22
|
+
CSV.foreach(File.join(File.dirname(__FILE__), 'elements.csv'), headers: true) do |row|
|
23
|
+
ELEMENTS << new(row)
|
24
|
+
end
|
25
|
+
|
26
|
+
private_class_method def self.method_missing(m, *args)
|
27
|
+
attribute = m.to_s.split('get_by_').last
|
28
|
+
valid_method? m, attribute
|
29
|
+
raise 'please give argument' if args.empty?
|
30
|
+
args[0] = attribute == 'name' ? args[0].capitalize : args[0]
|
31
|
+
element_data = get_element_by_attribute attribute, args[0]
|
32
|
+
raise 'Element not found' unless element_data
|
33
|
+
element_data
|
34
|
+
end
|
35
|
+
|
36
|
+
private_class_method def self.get_element_by_attribute(attribute, value)
|
37
|
+
ELEMENTS.each do |element|
|
38
|
+
# elements value of attribute == value give by user
|
39
|
+
return element if
|
40
|
+
element.instance_variable_get(('@' + attribute).intern) == value
|
41
|
+
end
|
42
|
+
raise(NameError, 'element not found')
|
43
|
+
end
|
44
|
+
|
45
|
+
private_class_method def self.valid_method?(m, attribute)
|
46
|
+
super unless m.to_s.start_with?('get_by_')
|
47
|
+
raise(NameError, 'Invalid attribute') unless ATTRS.include? attribute
|
48
|
+
end
|
49
|
+
|
50
|
+
private_class_method :new
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|