eulim 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- 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
|